`
wuxi7227
  • 浏览: 1604 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Ext.grid.PivotAxis的一个BUG

阅读更多
本人在工作中发现Ext.grid.PivotAxis的一个Bug。虽然说这玩意儿是一个半成品,新版本的EXTJS中已经找不到踪影,但是还是发表一下,以备用到过这玩意儿的程序员借鉴。已经在EXTJS的论坛报BUG :[url]http://www.sencha.com/forum/showthread.php?262138-A-bug-in-Ext.grid.PivotAxis [/url]  懒得看英文的话,在下在这里再解释一下。

该类的buildHeaders方法有如下代码片段

   buildHeaders: function() {
        var tuples     = this.getTuples(),
            rowCount   = tuples.length,
            dimensions = this.dimensions,
            dimension,
            colCount   = dimensions.length,
            headers    = [],
            tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
        
        for (i = 0; i < colCount; i++) {
            dimension = dimensions[i];
            rows  = [];
            span  = 0;
            start = 0;
            
            for (j = 0; j < rowCount; j++) {
                tuple  = tuples[j];
                isLast = j == (rowCount - 1);
                currentHeader = tuple.data[dimension.dataIndex];
                
                /*
                 * 'changed' indicates that we need to create a new cell. This should be true whenever the cell
                 * above (previousHeader) is different from this cell, or when the cell on the previous dimension
                 * changed (e.g. if the current dimension is Product and the previous was Person, we need to start
                 * a new cell if Product is the same but Person changed, so we check the previous dimension and tuple)
                 */
                changed = previousHeader != undefined && previousHeader != currentHeader;
                if (i > 0 && j > 0) {
                    changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
                }
                
                if (changed) {                    
                    rows.push({
                        header: previousHeader,
                        span  : span,
                        start : start
                    });
                    
                    start += span;
                    span = 0;
                }
                ......

该方法先循环列,再循环行,扫描计算是不是要画新的cell,计算之前的dimension的span。其中有一个逻辑不对,它只检查和上面一行的cell,或者之前一列上下行是否一样。而我认为需要检查当前cell之前的所有列的上下行是否一致。否则画出来的表格会比右边的数据行数少。把下面的文件放在examples\grid下去测一下就会发现:

<!DOCTYPE HTML>
<html>
<head>
<title>Test Page</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<!-- EID Theme CSS  -->
    <!-- ** CSS ** -->
    <!-- base library -->
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

    <!-- overrides to base library -->

    <!-- page specific -->
    <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
    <link rel="stylesheet" type="text/css" href="grid-examples.css" />

    <!-- ** Javascript ** -->
    <!-- ExtJS library: base/adapter -->
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>

    <!-- ExtJS library: all widgets -->
    <script type="text/javascript" src="../../ext-all-debug.js"></script>

<script type="text/javascript">

Ext.onReady(function() {
var SaleRecord = Ext.data.Record.create([
       {name: 'D1',   type: 'string'},
{name: 'D2',  type: 'string'},
{name: 'D3',     type: 'string'},
{name: 'D4',    type: 'string'},
{name: 'D5',     type: 'string'},
{name: 'D6',     type: 'string'},
{name: 'D7',     type: 'string'},
{name: 'D8',     type: 'string'},
{name: 'M1',    type: 'int'}
    ]);
var myData = [
{"id":"1","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d81","M1":"8888"},
{"id":"2","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d80","M1":"8887"},
{"id":"3","D1":"V1","D2":"Shanghai","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Hank","D7":"aa","D8":"d87","M1":"8886"},
{"id":"4","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d86","M1":"7878"},
{"id":"5","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ac","D8":"d85","M1":"7878"},
{"id":"6","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d84","M1":"7878"},
{"id":"7","D1":"V2","D2":"Beijing","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ab","D8":"d82","M1":"7878"},
{"id":"8","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"ac","D8":"d81","M1":"3333"},
{"id":"9","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Adam","D7":"er","D8":"d34","M1":"3333"},
{"id":"10","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Apple","D7":"df","D8":"d80","M1":"7878"},
{"id":"11","D1":"V2","D2":"Boston","D3":"1","D4":"Finance","D5":"Special Finance","D6":"Apple","D7":"df","D8":"d55","M1":"7878"}
];
// A simple store that loads SaleRecord data from a url
var myStore = new Ext.data.Store({
autoLoad: true,
proxy : new Ext.data.MemoryProxy(myData),
reader: new Ext.data.JsonReader({
}, SaleRecord),
});

// Create the PivotGrid itself, referencing the store
var pivot = new Ext.grid.PivotGrid({
title: 'PivotGrid example',
store     : myStore,
aggregator: 'sum',
measure   : 'M1',
renderTo : Ext.getBody(),
viewConfig: {
title: 'Sales Performance'
},
leftAxis: [
{
width: 60,
dataIndex: 'D1'
},
{
width: 150,
dataIndex: 'D2'
},
{
width: 60,
dataIndex: 'D3'
},
{
width: 60,
dataIndex: 'D4'
},
{
width: 60,
dataIndex: 'D5'
},
{
width: 60,
dataIndex: 'D6'
}
],

topAxis: [
{
dataIndex: 'D7'
},
{
dataIndex: 'D8'
}
]
});
});
</script>
</head>
<body>

</body>
</html>


所以我的fix如下:

isPrecedingChanged : function(tuples,dimensions,currentCol,currentRow){
						var changed = false;
						for(var col= currentCol; col>0; col--){
							if(tuples[currentRow].data[dimensions[col-1].dataIndex] != tuples[currentRow-1].data[dimensions[col-1].dataIndex]){
								changed = true;
								break;
							}
						}
						return changed;
					},

    buildHeaders: function() {
        var me = this, 
            tuples     = this.getTuples(),
            rowCount   = tuples.length,
            dimensions = this.dimensions,
            dimension,
            colCount   = dimensions.length,
            headers    = [],
            tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
        
        for (i = 0; i < colCount; i++) {
            dimension = dimensions[i];
            rows  = [];
            span  = 0;
            start = 0;
            
            for (j = 0; j < rowCount; j++) {
                tuple  = tuples[j];
                isLast = j == (rowCount - 1);
                currentHeader = tuple.data[dimension.dataIndex];
                
                /*
                 * 'changed' indicates that we need to create a new cell. This should be true whenever the cell
                 * above (previousHeader) is different from this cell, or when the cell on the previous dimension
                 * changed (e.g. if the current dimension is Product and the previous was Person, we need to start
                 * a new cell if Product is the same but Person changed, so we check the previous dimension and tuple)
                 */
                changed = previousHeader != undefined && previousHeader != currentHeader;
                if (i > 0 && j > 0) {
                    changed = changed || me.isPrecedingChanged(tuples,dimensions,i,j);
                }
                
                if (changed) {                    
                    rows.push({
                        header: previousHeader,
                        span  : span,
                        start : start
                    });
                    
                    start += span;
                    span = 0;
                }
                .......
分享到:
评论

相关推荐

    Ext.grid.GridPanel属性祥解

    每一项都是一个`Ext.grid.Column`实例。 - 示例:`columns: [{ header: '姓名', dataIndex: 'name' }, { header: '年龄', dataIndex: 'age' }]` 3. **autoExpandColumn** - 说明:此配置项指定了一个列ID,该列会...

    ExtJS 4.0 改善Ext.grid.plugin.RowEditing (重构,v1.4版本,2011-09-11)

    这篇文章的标题指出这是一个关于“Ext.grid.plugin.RowEditing”的重构,版本为v1.4,发布日期为2011年9月11日。重构通常意味着代码的改进,可能涉及性能优化、错误修复或功能增强。在4.0版本中,RowEditing插件的...

    可编辑表格Ext.grid.EditorGridPanel

    Ext.grid.EditorGridPanel是Ext JS库中的一个组件,主要用于创建具有可编辑单元格的表格。这个组件在数据展示和编辑方面提供了丰富的功能,是构建数据密集型应用的理想选择。下面将详细阐述其特点、工作原理及如何...

    Ext grid panel 滚动条位置不变

    Ext.override(Ext.grid.GridView, { scrollTop: function () { this.scroller.dom.scrollTop = 0; this.scroller.dom.scrollLeft = 0; }, scrollToTop: Ext.emptyFn }); ``` 这里的`scrollTop`方法将滚动条...

    Ext.get与Ext.fly的区别

    - **轻量级**:相比于`Ext.get`,`Ext.fly`更加轻量,因为每次调用都会创建一个新的`Ext.Element`实例,而不是缓存对象。 - **减少内存消耗**:对于只需要短暂操作的DOM元素而言,使用`Ext.fly`可以避免不必要的内存...

    Ext.ux.touch.grid-master.rar

    Ext.ux.touch.grid-master 是一个专门针对移动设备开发的JavaScript库,主要应用于开发触控友好的数据网格。这个压缩包包含的是EXTJS Touch框架的一个扩展组件,EXTJS Touch是Sencha公司开发的一个轻量级、高性能的...

    Ext.grid.ColumnModel显示不正常

    Ext.grid.ColumnModel显示不正常

    extjs-Ext.ux.form.LovCombo下拉框

    标题中的"extjs-Ext.ux.form.LovCombo下拉框"表明我们要讨论的是EXTJS中的一个特定组件,它是EXTJS的扩展插件,用于实现具有多选功能的下拉框。这个组件在处理火狐浏览器兼容性问题上做了优化,解决了在火狐浏览器下...

    封装Ext.grid.Grid+dwr实现增删该查

    `Ext.grid.Grid`是Ext JS库中的一个组件,用于创建可交互的数据网格,而DWR(Direct Web Remoting)则是一种允许JavaScript和Java在浏览器端进行安全、高效通信的技术。本篇文章将深入探讨如何利用这两者结合,实现...

    Ext.get与Ext.fly 的区别

    它接收一个DOM元素的ID或者一个DOM元素对象,返回一个`Ext.Element`对象。`Ext.Element`是对原生DOM元素的封装,提供了大量的实用方法,如样式设置、事件监听等。如果元素不存在,`Ext.get`会返回`null`。这是一个...

    Ext4.2的Ext.grid.plugin.RowExpander无法触发事件解决办法

    在Ext JS库中,`Ext.grid.plugin.RowExpander`是一个扩展插件,用于在网格行中添加可展开的详情区域。在Ext4.2版本中,用户可能遇到一个特定的问题,即`RowExpander`的`collapsebody`和`expandbody`事件无法正常触发...

    Ext.Ajax.request2.x实现同步请求

    在EXTJS库中,`Ext.Ajax.request`是用于发送Ajax请求的核心方法,它支持异步和同步操作。本文将详细解析如何利用`Ext.Ajax.request`实现同步请求,并探讨其背后的原理和注意事项。 首先,我们需要理解Ajax的本质,...

    Ext.grid.GridPanel 删除线

    Ext.grid.GridPanel 删除线 放到example文件夹下运行

    Ext.data.Store的基本用法

    在使用`Ext.data.Store`之前,首先需要创建一个其实例。创建实例时需要指定其配置项,主要包括`proxy`和`reader`,这两个配置项分别用来定义数据来源以及如何解析这些数据。 ```javascript var data = [ ['boy', 0...

    Ext.Store的获取方法

    然而,获取`Ext.Store`的方式并不像获取其他Ext组件那样直接,因为Store并不是一个具有可视界面的组件,它是一个纯粹的数据容器。 在传统的创建`Ext.Store`的方法中,我们通常会这样定义一个Store: ```javascript...

    Ext.Ajax.request跨域

    标题"Ext.Ajax.request跨域"指出我们将探讨如何使用ExtJS库中的Ajax模块进行跨域请求。Ext.Ajax.request是ExtJS提供的一种发起Ajax请求的方式,它允许开发者向服务器发送异步HTTP请求。然而,由于浏览器的同源策略...

    GridPanel中的单元格不能选中复制的解决方法

    Ext.grid.GridPanel 是一个功能强大且广泛使用的Grid控件,但是它存在一个很大的缺陷:单元格的内容不能选中,没法选中就没法复制,这给用户带来了很多不便。这个问题的根源在于ExtJs输出的代码中,每个单元格的div...

    一个简单的Ext.Window中插入图片的例子

    在Ext JS这个强大的JavaScript框架中,`Ext.Window`是一个常用组件,用于创建浮动、可弹出的窗口。在Web应用程序中,我们常常需要在这些窗口中展示各种内容,包括文字、表格、按钮,当然还有图片。本文将详细介绍...

    extjs4.1-ux.rar

    2、Ext.ux.grid.feature.Tileview 3、Ext.ux.upload.Button 4、Ext.ux.toggleslide.ToggleSlide 5、Ext.ux.container.ButtonSegment 6、Ext.ux.grid.plugin.RowEditing 7、Ext.ux.grid.plugin.DragSelector 8、Ext....

    org.restlet.ext.spring.jar

    org.restlet.ext.spring.jar

Global site tag (gtag.js) - Google Analytics