Hello I am making a piechart in EXTJS. The legends of these charts are not displaying properly they are being cut off. Therefore i am making a piechart in one panel and just under that i am making another panel which would contain the legends.
My question is how do I connect the pie chart in one panel and showing the legend of this pie chart in another panel.
I am using EXTJS 4.2
I am made 2 panels one is under the other in a vbox positioning.
Hope this will help you:
View
layout: {
type: 'vbox',
align: 'stretch'
},
dockedItems: [
{
xtype: 'toolbar',
flex: 1,
dock: 'top',
ui: 'tools',
items: [
{
xtype: 'tbspacer',
flex: 1
},
{
xtype: 'label',
html: '<span style="font-weight:bold">Sales by Category</span>'
},
{
xtype: 'tbspacer',
flex: 1
},
{
xtype: 'button',
iconCls: 'x-fa fa-download',
text: 'Download',
listeners: {
click: 'onDownloadButtonClick'
}
}
]
}
],
items: [
{
xtype: 'polar',
reference: 'salesByCategoryChartRef',
flex: 1,
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111',
'#009900',
'#6600cc'
],
insetPadding: '10',
innerPadding: 10,
bind: {
store: '{currentCategoryStore}'
},
series: [
{
type: 'pie',
highlight: true,
label: {
field: 'description',
display: 'none',
font: '12px Arial',
contrast: true
},
tooltip: {
trackMouse: true,
renderer: 'onSeriesTooltipRender'
},
angleField: 'sales'
}
],
interactions: [
{
type: 'rotate'
}
],
legend: {
xtype: 'legend',
docked: 'right'
}
}
],
Controller:
onSeriesTooltipRender: function(tooltip, record, item) {
var html = 'Code: ' + record.get('code') +' <br/> Description: ' +
record.get('description') + '<br/> Sale: ' + record.get('sales') + '%';
tooltip.setHtml(html);
},
onDownloadButtonClick: function(button, e, eOpts) {
if (Ext.isIE8) {
Ext.Msg.alert('Unsupported Operation', 'This operation requires a newer version of Internet Explorer.');
return;
}
var chart = this.lookupReference('salesByCategoryChartRef');
if (Ext.os.is.Desktop) {
chart.download({
filename: 'Sales by Category'
});
} else {
chart.preview();
}
},
Here is the output
PIE Chart
Related
In Extjs, i want to add button in tbar chart, which hide/unhide my grid, i have some difficult with layout, so in certains case, my button take 100% place, also my grid disapear, my code is bellow:
var barchart = {
xtype: 'cartesian',
legend: {
docked: 'bottom'
},
tbar: [{
xtype: 'container',
layout: {
type: 'vbox',
columns: 1,
align: 'stretch'
},
items: [{
xtype: 'button',
text: 'Afficher DSO',
listeners: {
click: function(btn){
var dsoGrid = btn.nextSibling();
if( dsoGrid.hidden ){
helperCache.multiToolbox(dsoGrid, ["NOT_HIDE"]);
btn.setText("Masquer DSO");
} else {
helperCache.multiToolbox(dsoGrid, ["HIDE"]);
btn.setText("Afficher DSO");
}
}
}
},{
xtype: 'grid',
itemId: 'grid_history_dso',
// hidden: true,
scrollable: 'x',
margin: 5,
flex: 1,
store: dsoStore,
columns: dsoColumns,
}]
}],
.......
I like to my button take normal size, and my grid take fit all place of his container with x scroll
For helping anyone in same case, i solved my problem with :
var barchart = {
xtype: 'cartesian',
legend: {
docked: 'bottom'
},
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
layout: {
type: 'anchor',
},
items: [{
xtype: 'button',
text: 'Afficher DSO',
listeners: {
click: function(btn){
var dsoGrid = btn.nextSibling();
if( dsoGrid.hidden ){
helperCache.multiToolbox(dsoGrid, ["NOT_HIDE"]);
btn.setText("Masquer DSO");
} else {
helperCache.multiToolbox(dsoGrid, ["HIDE"]);
btn.setText("Afficher DSO");
}
}
}
},{
xtype: 'grid',
itemId: 'grid_history_dso',
hidden: true,
scrollable: 'x',
margin: 5,
anchor: '100%',
store: dsoStore,
columns: dsoColumns,
}]
}],
dockedItem was key
I'm trying to create a panel like:
with the below code as a beginning, however I'm not sure how can I create a list/table inside a panel in a way like it looks below in the image.
I also have to load the data dynamically inside the panel.
also I'm using panel since I want it to be a collapsible one
$cls.superclass.constructor.call(this, Ext.apply({
items: [
this.section({
items: [
this.panel = new Ext.Panel({
items: [
this.section({
items: []
})
],
collapsible: true,
})
]
})
]
}, cfg));
Ext.extend($cls, Panel, {
getData: function(data) {
//here I have the entire data I want to show in the list. just not sure how?
}
});
any ideas?
You can create custom rows with Ext.Panel. The example shows only show creating list. To add part where AND, OR you can change structure of data and create row with nested panel row.
Here is example of creating custom list with panel:
Ext.onReady(function () {
Ext.create({
xtype: 'panel',
renderTo: Ext.getBody(),
title: 'ExtJS Master Panel',
items: [
collapsibleList = new Ext.Panel({
title: 'Collapsible List',
collapsible: true,
hideBorders: true,
padding: '10px',
height: 400
})
],
getData: function () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve([{
name: 'Last VM Scan',
decider: 'LESS THAN',
period: '30 days'
}, {
name: 'Last CERTVIEW Scan',
decider: 'LESS THAN',
period: '14 day'
}, {
name: 'Last checked In',
decider: 'LESS THAN',
period: '10 days'
}]);
}, 1000);
});
},
listeners: {
afterrender: function () {
console.log(collapsibleList);
Promise.resolve(this.getData()).then(function (data) {
for (var i = 0; i < data.length; i++) {
var pan = new Ext.Panel({
xtype: 'panel',
layout: 'hbox',
hideBorders: true,
items: [{
xtype: 'panel',
padding: '10px',
width: 200,
items: [{
xtype: 'label',
text: data[i].name
}]
}, {
xtype: 'panel',
padding: '10px',
width: 300,
items: [{
xtype: 'label',
text: data[i].decider
}]
}, {
xtype: 'panel',
padding: '10px',
items: [{
xtype: 'label',
text: data[i].period
}]
}]
});
collapsibleList.add(pan);
}
collapsibleList.doLayout();
});
}
}
});
});
Working Fiddle Link: https://fiddle.sencha.com/#view/editor&fiddle/2l14
I am trying to make two lists in a same view, I am separating the view in two flex boxes and inside of this includes each list but it is not working properly.. any clue of this implementation or suggestion? I am working with Sencha Touch 2.3.1 framework.
Thanks in advance.
/**
* The home view
*/
Ext.define('xx.view.home.BlocksHome', {
extend : 'Ext.Container',
xtype : 'blocksHome',
requires: [
'Ext.TitleBar',
'Ext.dataview.List',
'xx.view.news.News'
],
config : {
items: [
// selection container
{
xtype : 'container',
cls : 'home-container',
flex : 2,
layout : {
type : 'hbox',
align: 'stretch'
},
defaults: {
xtype : 'container',
styleHtmlContent: true,
flex : 1
},
items : [
// Data Collection
{
cls : 'news-container',
iconCls: 'inbox',
height: 800,
layout: 'vbox',
items: [
{
cls : 'news-collection-header',
layout: 'hbox',
items: [
{
html: '<h4>' + xx.Text.getText('NEWS') +'</h4>',
flex: 2
},
{
xtype : 'button',
itemId: 'toNewsCollection',
iconCls: 'inbox',
text : xx.Text.getText('NEWS'),
flex: 1
},
{
xtype: 'news',
layout: 'card'
}
]
}
]
},
// Customers
{
cls : 'open-activities',
layout: 'vbox',
items: [
{
cls : 'open-activities-header',
layout: 'hbox',
items : [
{
html: '<h4>' + xx.getText('ACTIVITY_LIST_TITLE') +'</h4>',
flex: 2
},
{
xtype : 'button',
itemId: 'toActivitiesCollection',
iconCls: 'check2',
text : xx.Text.getText('ACTIVITY_LIST_TITLE'),
flex: 1
}
]
}
]
}
]
}
]
}
});
And here the view include in a card layout named "news"
Ext.define('xx.view.news.List', {
extend: 'Ext.dataview.List',
xtype: 'news',
requires: [
'Ext.TitleBar',
'Ext.plugin.PullRefresh'
],
config: {
plugins: [
{
xclass: 'Ext.plugin.PullRefresh',
listeners: {
painted: function(element) {
if (Ext.browser.is.IE) {
// position pull to refresh centered
Ext.get(element.query('.x-list-pullrefresh')[0]).setStyle('left', (Ext.getBody().getWidth() / 2) - 132 + 'px');
}
}
}
}
],
store: 'News',
itemTpl: '<div class="newslistline">' +
' <div class="newssubject"><tpl if="unread == \'true\'"><span style class="newsNew">new</span></tpl>{subject}</div>' +
' <div class="newsupdatedate">{[xx.Helper.formatSAPdate2Str(values.updatedate)]}</div>' +
' <div class="newsupdateby">{responsible}</div>' +
' <div class="newsattachment {[values.attflag == \'true\'? \'attachment\' : \' \']}">' +
' </div>' +
' </div>',
emptyText: xx.Text.getText('NEWS_LIST_EMPTY'),
loadingText: xx.Text.getText('NEWS_LIST_LOADING'),
items: [
{
docked: 'top',
xtype: 'titlebar',
title: xx.Text.getText('NEWS_LIST_TITLE')
}
]
}
});
Add flex:1 to each list. Here is a working example I created using Sencha Fiddle.
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('News', {
extend: 'Ext.data.Model',
config: {
fields: ['subject']
}
});
var store1 = Ext.create('Ext.data.Store', {
model: 'News',
data: [{
subject: 'Item1'
}, {
subject: 'Item2'
}]
});
var store2 = Ext.create('Ext.data.Store', {
model: 'News',
data: [{
subject: 'Record1'
}, {
subject: 'Record2'
}]
});
Ext.define('xx.view.news.List', {
extend: 'Ext.List',
xtype: 'news',
requires: ['Ext.TitleBar'],
emptyText: 'Empty',
loadingText: 'Loading',
config: {
itemTpl: '<div class="newslistline">{subject}</div>'
}
});
Ext.create("Ext.Container", {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
xtype: 'container',
cls: 'home-container',
flex: 2,
layout: {
type: 'hbox',
align: 'stretch'
},
defaults: {
xtype: 'container',
styleHtmlContent: true,
flex: 1
},
items: [{
cls: 'news-container',
iconCls: 'inbox',
height: 800,
layout: 'vbox',
items: [{
cls: 'news-collection-header',
layout: 'hbox',
items: [{
html: '<h4>Title</h4>',
flex: 2
}, {
xtype: 'button',
itemId: 'toNewsCollection',
iconCls: 'inbox',
text: 'Something',
flex: 1
}]
}, {
xtype: 'news',
flex: 1,
store: store1
}]
}, {
cls: 'open-activities',
layout: 'vbox',
items: [{
cls: 'open-activities-header',
layout: 'hbox',
items: [{
html: '<h4>Title</h4>',
flex: 2,
itemTpl: '<div class="newslistline">{subject}</div>'
}, {
xtype: 'button',
itemId: 'toActivitiesCollection',
iconCls: 'check2',
text: 'Something',
flex: 1
}]
}, {
xtype: 'news',
flex: 1,
store: store2
}]
}]
}]
});
}
});
I have an issue in my recent implemented Rally Grid.
_CreatePSIObjectiveGrid: function(myStore) {
if (!this.objGrid) {
var colCfgs = [{
text: 'ID',
dataIndex: 'DragAndDropRank',
width: 50
}, {
text: 'Summary',
dataIndex: 'Name',
flex: 1
}, {
text: 'Success Rate',
dataIndex: 'c_SuccessRate',
width: 200
}];
if (!this.getSetting("useSuccessRatioOnly")) {
colCfgs.push({
text: 'Initial Business Value',
dataIndex: 'PlanEstimate',
width: 200
});
colCfgs.push({
text: 'Final Business Value',
dataIndex: 'c_FinalValue',
width: 200
});
}
this.objGrid = Ext.create('Rally.ui.grid.Grid', {
store : myStore,
enableRanking: true,
defaultSortToRank: true,
height: 550,
overflowY: 'auto',
margin: 10,
showPagingToolbar: false,
columnCfgs : colCfgs
});
Ext.getCmp('c-panel-obj-crud-table').add(this.objGrid);
}
}
Although I have set "enableRanking" to "true", the ranking drag and drop doesn't work if I add my grid to a component. However, the drag and drop function does work perfectly if I change the last statement from
Ext.getCmp('c-panel-obj-crud-table').add(this.objGrid);
to
this.add(this.objGrid);
I don't know if this is a Rally bug. Try to compare the final html file generated, no clue is found.
this few sec video shows that the code below, where a rankable grid is added to a child panel, and not directly to this (this points to the app's global scope) still preserves its ability to rerank:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var panel = Ext.create('Ext.panel.Panel', {
layout: 'hbox',
itemId: 'parentPanel',
componentCls: 'panel',
items: [
{
xtype: 'panel',
title: 'Panel 1',
width: 600,
itemId: 'childPanel1'
},
{
xtype: 'panel',
title: 'Panel 2',
width: 600,
itemId: 'childPanel2'
}
],
});
this.add(panel);
this.down('#childPanel1').add({
xtype: 'rallygrid',
columnCfgs: [
'FormattedID',
'Name',
'ScheduleState',
'Owner'
],
context: this.getContext(),
enableRanking: true,
defaultSortToRank: true,
storeConfig: {
model: 'userstory'
}
});
}
});
I am trying to get an instance of my view within the controller. How can I accomplish this. The main reason I am trying to do this is that I have a grid in my view that I want to disable until a selection from a combobox is made so I need to have access to the instance of the view.
Help?
My controller:
Ext.define('STK.controller.SiteSelectController', {
extend: 'Ext.app.Controller',
stores: ['Inventory', 'Stacker', 'Stackers'],
models: ['Inventory', 'Stackers'],
views: ['scheduler.Scheduler'],
refs: [{
ref: 'stackerselect',
selector: 'panel'
}],
init: function () {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
/* render all default functionality */
onPanelRendered: function () {
var view = this.getView('Scheduler'); // this is null?
}
});
My view:
Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', '/extjs/examples/ux');
Ext.require([
'Ext.ux.grid.FiltersFeature',
'Ext.ux.LiveSearchGridPanel']);
var filters = {
ftype: 'filters',
autoReload: false,
encode: false,
local: true
};
Ext.define('invtGrid', {
extend: 'Ext.ux.LiveSearchGridPanel',
alias: 'widget.inventorylist',
title: 'Inventory List',
store: 'Inventory',
multiSelect: true,
padding: 20,
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'invtGridDDGroup',
dropGroup: 'stackerGridDDGroup'
},
listeners: {
drop: function (node, data, dropRec, dropPosition) {
var dropOn = dropRec ? ' ' + dropPosition + ' ' + dropRec.get('ordNum') : ' on empty view';
}
}
},
features: [filters],
stripeRows: true,
columns: [{
header: 'OrdNum',
sortable: true,
dataIndex: 'ordNum',
flex: 1,
filterable: true
}, {
header: 'Item',
sortable: true,
dataIndex: 'item',
flex: 1,
filterable: true
}, {
header: 'Pcs',
sortable: true,
dataIndex: 'pcs',
flex: 1,
filterable: true
}]
});
Ext.define('stackerGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.stackerselect',
title: 'Stacker Select',
store: 'Stacker',
padding: 20,
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'stackerGridDDGroup',
dropGroup: 'invtGridDDGroup'
},
listeners: {
drop: function (node, data, dropRec, dropPosition) {
var dropOn = dropRec ? ' ' + dropPosition + ' ' + dropRec.get('ordNum') : ' on empty view';
}
}
},
columns: [{
header: 'OrdNum',
dataIndex: 'ordNum',
flex: 1
}, {
header: 'Item',
dataIndex: 'item',
flex: 1
}, {
header: 'Pcs',
dataIndex: 'pcs',
flex: 1
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
text: 'Submit',
action: 'submit'
}, {
text: 'Reset',
action: 'reset'
}]
}, {
xtype: 'toolbar',
dock: 'top',
items: [{
id: 'combo',
xtype: 'combobox',
queryMode: 'local',
fieldLabel: 'Stacker',
displayField: 'stk',
valueField: 'stk',
editable: false,
store: 'Stackers',
region: 'center',
type: 'absolute'
}]
}]
});
Ext.define('STK.view.scheduler.Scheduler', {
extend: 'Ext.panel.Panel',
alias: 'widget.schedulerview',
title: "Scheduler Panel",
layout: {
type: 'column'
},
items: [{
xtype: 'inventorylist',
width: 650,
height: 600,
columnWidth: 0.5,
align: 'stretch'
}, {
xtype: 'stackerselect',
width: 650,
height: 600,
columnWidth: 0.5
}]
});
As I said, Extjs creates getter for your views (those listed in the controller's view array) and you get access to them:
var view = this.getSchedulerSchedulerView();
Once you have the view reference you can do this to get access to the contained grid:
var grid = view.down('.inventorylist');
grid.disable();