2013-07-08 2 views
1

I과 유사한는 ExtJS에 그룹화 된 막대 그래프를 플롯하려고를 사용하여 그룹화 막대 차트를 만드는 방법 센차의 example.의 ExtJS -> 2 개 관련 모델에게 (hasMany의 관계)

당신은의 필드 필드를 사용할 수 모델 xField/yField의 차트의 상점 모델에 속하는 하위 모델?

"GolfClubs"이 많은 "Golfer"모델의 경우 골퍼에 속한 각 GolfClub에 대한 막대를 표시하는 그룹화 된 막대 차트를 렌더링 할 수 있습니까 (각 골퍼의 이름은 축 레이블이됩니까)? 엽차의 예에서

가게가 하나 개의 레코드에있는 모든 데이터를 가지고 있지만 나는 그것이 모델 관련된 "hasMany의"자동으로 결합 할 수 있겠죠?

// 모델

Ext.define('GolfClub', { 

extend : 'Ext.data.Model', 

fields : [{ 
    name : 'ClubType', 
    type : 'string' 
}, { 
    name : 'Weight', 
    type : 'float' 
}] 

}); 

Ext.define('Golfer', { 
    extend : 'Ext.data.Model', 
    requires: ['GolfClub'], 
    fields : [{ 
     name : 'GolferName', 
     type : 'string' 
    }], 

    hasMany: {model: 'GolfClub', name: 'golfClubs'} 
}); 

// 최종 모델

// 현지 데이터 (그냥 작업하기가 첫번째)

function data(){ 

var golfers = []; 
    var rory = Ext.create('Golfer', { 
     GolferName : 'Rory' 
    }); 

    var rorysDriver = Ext.create('GolfClub', { 
     ClubType : 'Driver', 
     Weight : 80 
    }); 

var rorysPutter = Ext.create('GolfClub', { 
     ClubType : 'Putter', 
     Weight : 60 
    }); 

var rorysSandWedge = Ext.create('GolfClub', { 
     ClubType : 'SandWedge', 
     Weight : 50 
    }); 

    var rorysClubs = rory.golfClubs(); 

    rorysClubs.add(rorysDriver); 
    rorysClubs.add(rorysPutter); 
    rorysClubs.add(rorysSandWedge); 

    golfers.push(rory); 



    var tiger = Ext.create('Golfer', { 
     GolferName : 'Tiger' 
    }); 

    var tigersDriver = Ext.create('GolfClub', { 
     ClubType : 'Driver', 
     Weight : 85 
    }); 

var tigersPutter = Ext.create('GolfClub', { 
     ClubType : 'Putter', 
     Weight : 55 
    }); 

var tigersSandWedge = Ext.create('GolfClub', { 
     ClubType : 'SandWedge', 
     Weight : 58 
    }); 

    var tigersClubs = tiger.golfClubs(); 

    tigersClubs.add(tigersDriver); 
    tigersClubs.add(tigersPutter); 
    tigersClubs.add(tigersSandWedge); 

    golfers.push(tiger); 

return golfers; 
} 

// 종료 로컬 데이터

// Local Store

function store1(){ 
var golferStore = Ext.create('Ext.data.Store', { 
    model: 'Golfer', 
    data : data()}); 

return golferStore; 
} 

// 끝 지역 상점

Ext.onReady(function() { 
     var chart = Ext.create('Ext.chart.Chart', { 
     style: 'background:#fff', 
     animate: true, 
     shadow: true, 
     store: store1(), 
     legend: { 
      position: 'right' 
     }, 
     axes: [{ 
      type: 'Numeric', 
      position: 'bottom', 
      fields: ['golfClubs.Weight'] 
     }, { 
      type: 'Category', 
      position: 'left', 
      fields: ['GolferName'], 
      title: 'Golfer' 
     }], 
     series: [{ 
      type: 'bar', 
      axis: ['bottom'], 
      xField: ['golfClubs.Weight'],//Is that how you bind to child record? 
      yField: ['GolferName'] 
     }] 
    }); 


var win = Ext.create('Ext.Window', { 
    width: '100%', 
    height: '100%', 
    title: 'Breakdown of Golfers and their Clubs..', 
    autoShow: true, 
    layout: 'fit', 
    items: chart 
}); 
}); 

건배, 톰.

답변

2

이 경우 누구의 엽차 포럼에서이 문제에 관심이 대답했습니다.

차트의 저장소는 모든 데이터/레코드가 저장소에 채워져 있어야합니다 (-vs- 각 레코드가 상위 레코드로 채워지고 각 테이블에 자체 하위 레코드 세트가 있음). 그래서, 나는 당신이하고 싶은 것을 두려워합니다. 직접 할 수는 없습니다.

Answer from Sencha Support Team Member

이 솔루션은 groupField 연장 시리즈와 결합 차트의 상점에서 사용할 수있는 새로운 모델로 부모와 자식 모델의 필드의 병합 될 것으로 보인다.

Ext.define('Result', { 
    extend: 'Ext.data.Model', 
    fields: [ 
     { name: 'state', type: 'string', mapping:0 }, 
     { name: 'product', type: 'string', mapping:1 }, 
     { name: 'quantity', type: 'int', mapping:2 } 
    ] 
}); 
var store = Ext.create('Ext.data.ArrayStore', { 
    model: 'Result', 
    groupField: 'state', 
    data: [ 
     ['MO','Product 1',50], 
     ['MO','Product 2',75], 
     ['MO','Product 3',25], 
     ['MO','Product 4',125], 
     ['CA','Product 1',50], 
     ['CA','Product 2',100], 
     ['WY','Product 1',250], 
     ['WY','Product 2',25], 
     ['WY','Product 3',125], 
     ['WY','Product 4',175] 
    ] 
}); 

Ext.define('Ext.chart.series.AutoGroupedColumn', { 
    extend: 'Ext.chart.series.Column', 
    type: 'autogroupedcolumn', 
    alias: 'series.autogroupedcolumn', 
    gField: null, 
    constructor: function(config) { 
     this.callParent(arguments); 
     // apply any additional config supplied for this extender 
     Ext.apply(this, config); 
     var me = this, 
      store = me.chart.getStore(), 
      // get groups from store (make sure store is grouped) 
      groups = store.isGrouped() ? store.getGroups() : [], 
      // collect all unique values for the new grouping field 
      groupers = store.collect(me.gField), 
      // blank array to hold our new field definitions (based on groupers collected from store) 
      fields = []; 
     // first off, we want the xField to be a part of our new Model definition, so add it first 
     fields.push({name: me.xField }); 
     // now loop over the groupers (unique values from our store which match the gField) 
     for(var i in groupers) { 
      // for each value, add a field definition...this will give us the flat, in-record column for each group 
      fields.push({ name: groupers[i], type: 'int' }); 
     } 
     // let's create a new Model definition, based on what we determined above 
     Ext.define('GroupedResult', { 
      extend: 'Ext.data.Model', 
      fields: fields 
     }); 
     // now create a new store using our new model 
     var newStore = Ext.create('Ext.data.Store', { 
      model: 'GroupedResult' 
     }); 
     // now for the money-maker; loop over the current groups in our store 
     for(var i in groups) { 
      // get a sample model from the group 
      var curModel = groups[ i ].children[ 0 ]; 
      // create a new instance of our new Model 
      var newModel = Ext.create('GroupedResult'); 
       // set the property in the model that corresponds to our xField config 
       newModel.set(me.xField, curModel.get(me.xField)); 
      // now loop over each of the records within the old store's current group 
      for(var x in groups[ i ].children) { 
       // get the record 
       var dataModel = groups[ i ].children[ x ]; 
       // get the property and value that correspond to gField AND yField 
       var dataProperty = dataModel.get(me.gField); 
       var dataValue = dataModel.get(me.yField); 
       // update the value for the property in the Model instance 
       newModel.set(dataProperty, dataValue); 
       // add the Model instance to the new Store 
       newStore.add(newModel); 
      } 
     } 
     // now we have to fix the axes so they work 
     // for each axes... 
     me.chart.axes.each(function(item, index, len) { 
      // if array of fields 
      if(typeof item.fields=='object') { 
       // loop over the axis' fields 
       for(var i in item.fields) { 
        // if the field matches the yField config, remove the old field and replace with the grouping fields 
        if(item.fields[ i ]==me.yField) { 
         Ext.Array.erase(item.fields, i, 1); 
         Ext.Array.insert(item.fields, i, groupers); 
         break; 
        } 
       } 
      } 
      // if simple string 
      else { 
       // if field matches the yField config, overwrite with grouping fields (string or array) 
       if(item.fields==me.yField) { 
        item.fields = groupers; 
       } 
      } 
     }); 
     // set series fields and yField config to the new groupers 
     me.fields,me.yField = groupers; 
     // update chart's store config, and re-bind the store 
     me.chart.store = newStore; 
     me.chart.bindStore(me.chart.store, true); 
     // done! 
    } 
}) 

Ext.create('Ext.chart.Chart', { 
    renderTo: Ext.getBody(), 
    width: 500, 
    height: 300, 
    animate: true, 
    store: store, 
    legend: { 
     position: 'right' 
    }, 
    axes: [ 
     { 
      type: 'Numeric', 
      position: 'left', 
      fields: ['quantity'], 
      label: { 
       renderer: Ext.util.Format.numberRenderer('0,0') 
      }, 
      title: 'Quantity', 
      grid: true, 
      minimum: 0 
     }, 
     { 
      type: 'Category', 
      position: 'bottom', 
      fields: ['state'], 
      title: 'State' 
     } 
    ], 
    series: [ 
     { 
      type: 'autogroupedcolumn', 
      axis: 'left', 
      highlight: true, 
      xField: 'state', 
      yField: 'quantity', 
      gField: 'product' 
     } 
    ] 
}); 

here

1

그리고 그것을 밖으로 시도에 대한 센차 바이올린으로 참조하십시오 https://fiddle.sencha.com/#fiddle/207

+0

을이 링크 질문에 대답 할 수 있지만, 여기에 해답의 본질적인 부분을 포함하고 제공하는 것이 좋습니다 링크를 참조하십시오. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. - [From Review] (리뷰/저품절 게시물/16974038) –