Note:
This is a cross post at:extjsForum
since I got no answer there,so I ask here.
Anyone who decide to answer this post can see the forum first to make sure if the question has been answer. :)
The following is my core code to make a Column chart to show the visitors and bytes of my website, however I found that I can not handle the label of the xAxis.
visitAndBytesStore = new Ext.data.JsonStore(
{
fields :
[
{
name : 'time',
type : 'string'
// dateFormat : 'Y-m-d H:i:s'
}, 'visits', 'bytes' ]
});
var visitAndBytesData =
[{"time" : "2010-09-17 16:24:06","visits" : "23","bytes" : "4545"},
{"time" : "2010-09-17 02:23:33","visits" : "3233","bytes" : "3232"},
{"time" : "2010-09-17 16:23:52","visits" : "456","bytes" : "3242342"},
{"time" : "2010-09-17 15:23:52","visits" : "6456","bytes" : "2314252"} ];
visitAndByteChart = new Ext.chart.ColumnChart(
{
store : visitAndBytesStore,
xField : 'time',
// xAxis : new Ext.chart.TimeAxis(
// {
// title : 'time',
// displayName : 'time',
// labelRenderer : function(dd)
// {
// // return dd.format("m-d")+"\n"+dd.format("H:i");
// return "";
// }
// }),
yAxis : new Ext.chart.NumericAxis(
{
displayName : 'Visits',
labelRenderer : Ext.util.Format.numberRenderer('0,0')
}),
series :
[
{
type : 'column',
displayName : 'Bytes',
yField : 'bytes',
style :
{
color : 0x99BBE8
}
},
{
type : 'line',
displayName : 'Visits',
yField : 'visits',
style :
{
mode : 'stretch',
color : 0x15428B
}
} ]
});
visitorAndBytesChartPanel = new Ext.Panel(
{
iconCls : 'chart',
title : ' ',
frame : true,
renderTo : 'bytes',
autoWidth : true,
height : 300,
layout : 'fit',
items : visitAndByteChart
});
As shown above if I use the "string" format of the "time" field, I can not handle the format of the time label in the chart, their value are too long (2010-09-20 23:00:00 is too long),so they are displayed by Automaticly chosed.
This is the result:
http://awesomescreenshot.com/0e41vu0c0
I want all of them displayed.
So I set the "time" field to "date" (Just remove the comments in the above codes),
And now the last label in the chart can not displayed completely,so is the "dot" in the chart which trig the tip event.
This is the result:
http://awesomescreenshot.com/04c1vtq94
Is there any problems?
extraStyle: {
padding: 20
}
From the Forum
Related
I am using Ext flot for drawing charts on my application. I want to update chart data with ajax request or with a button. I couldn't update values. Anyone have an idea?
var graphDataArr = [{ label: 'My Graph', data: myDataArray, color: '#46F252', hoverable: false, clickable: false }];
new Ext.Window({
header : false,
layout : 'anchor',
height : 200,
width : 750,
baseCls : 'ext_panel_header_bar',
items : [ {
xtype : 'flot',
id : 'flotGraph',
cls : 'x-panel-body',
series : graphDataArr,
xaxis : {
min : xMin,
max : xMax
},
yaxis : {
min : yMin,
max : yMax
},
tooltip : false,
anchor : '98% 99%'
} ]
}).show();
Ext Flot API documentation says:
setData( Array Series ) : void
You can use this to reset the data used. Note that axis scaling, ticks, legend etc. will not be recomputed (use setupGrid() to do that). You'll probably want to call draw() afterwards.
You can use this function to speed up redrawing a plot if you know that the axes won't change. Put in the new data with setData(newdata) and call draw() afterwards, and you're good to go.
You could do the following in a button handler (where dataArray is your new data array):
var chart = Ext.getCmp('flotGraph');
chart.setData(dataArray);
chart.setupGrid();
chart.draw();
if you have send record from your web Application in Json/Proper format then you can simply create JavaScript that you can call on button /submit button.
function createCharts() {
var queryString = $('#mainForm').formSerialize();
var url_String = "runChartData.action" + '?'+queryString+'&selectedModule=Line';// URL to call ajax
$.ajax({
type: "post",
dataType: "json",
url: url_String,
async : true,
success: function(data){
chartData = data;
createChart(data); // the Method you have Created As I have created Bellow
}, error: function(data){
$('#chartDiv').empty(); //empty chart Div to recreate it.
}
});
}
createChart(var myDataArray){
$('#chartDiv').empty(); // reset to Create New Chart with new Data
var graphDataArr = [{ label: 'My Graph', data: myDataArray, color: '#46F252', hoverable: false, clickable: false }];
new Ext.Window({
header : false,
layout : 'anchor',
height : 200,
width : 750,
baseCls : 'ext_panel_header_bar',
items : [ {
xtype : 'flot',
id : 'flotGraph',
cls : 'x-panel-body',
series : graphDataArr,
xaxis : {
min : xMin,
max : xMax
},
yaxis : {
min : yMin,
max : yMax
},
tooltip : false,
anchor : '98% 99%'
} ]
}).show();
}
I'm trying to work out why when I push a view onto a Ext.Navigation.View control, the view I push renders, but the data I push with it doesn't. The view renders a very simple DataView control with some json data (name & surname).
It'll work if I create the view explicitly through "Ext.Create" (see commented out lines in controller), but I'm sure I've done this before where you can push "xtype" of the view and any relevant properties/data for the view. Am I right?
By the way, I've tested the json coming back from the form submission callback and everything is fine. It just seems to be the view doesn't want to render the data I send it as part of the "push". Here's my code. Am I missing something?:
View:
Ext.define('MyCo.Booking.view.PatientClinicSearchResults', {
extend : 'Ext.DataView',
xtype : 'DataViewPatientSearchResults',
itemTpl : '{Name}',
store : {
fields : ['Name'],
autoLoad : true
}
})
Controller :
Ext.define('MyCo.Booking.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
navViewClinics : 'NavViewClinics',
formPanelClinicPatientSearch : 'FormPanelClinicPatientSearch'
},
control: {
'NavViewClinics list' : {
itemtap : 'ClinicUserSearch'
},
'FormPanelClinicPatientSearch button' : {
tap : 'ClinicPatientSearchResults'
}
}
},
ClinicUserSearch : function(list, index, element, record) {
this.getNavViewClinics().push({ xtype : 'FormPanelClinicPatientSearch' });
},
ClinicPatientSearchResults : function(button, e) {
var form = this.getFormPanelClinicPatientSearch();
var navClinics = this.getNavViewClinics();
form.submit({
success : function(form, result) {
// var view = Ext.create('MyCo.Booking.view.PatientClinicSearchResults', {
// title : 'Search Results',
// fullscreen: true,
// store: {
// fields: ['Name'],
// data : result.items
// },
// itemTpl: '<div>{Name}</div>'
// });
// navClinics.push(view);
navClinics.push({ xtype : "DataViewPatientSearchResults",
title : 'Test',
store : {
data : result.items
}
});
}
});
}
});
JSON received from form submission callback:
{
"success" : true,
"items" : [
{
"Name": "Jon",
"Surname": "Doe"
},
{
"Name": "Karl",
"Surname": "Doe"
}
]
}
Any help would be appreciated. Thank you.
Problem solved. I removed the store declaration from the view and it worked. Just need to reference the data via the itemTpl property.
Am trying to put a search field with respect to a data view. There is a toolbar on top of the data view, which consists of a text field. On entering some text in the field, i want to call a search functionality. As of now, i have got hold of the listener to the text field, but the listener is called immediately after the user starts typing something in the text field.
But, what am trying to do is to start the search functionality only when the user has entered at least 3 characters in the text field.How could i do this?
Code below
View
var DownloadsPanel = {
xtype : 'panel',
border : false,
title : LANG.BTDOWNLOADS,
items : [{
xtype : 'toolbar',
border : true,
baseCls : 'subMenu',
cls : 'effect1',
dock : 'top',
height : 25,
items : [{
xtype : 'textfield',
name : 'SearchDownload',
itemId : 'SearchDownload',
enableKeyEvents : true,
fieldLabel : LANG.DOWNLOADSF3,
allowBlank : true,
minLength : 3
}],
{
xtype : 'dataview',
border : false,
cls : 'catalogue',
autoScroll : true,
emptyText : 'No links to display',
selModel : {
deselectOnContainerClick : false
},
store : DownloadsStore,
overItemCls : 'courseView-over',
itemSelector : 'div.x-item',
tpl : DownloadsTpl,
id : 'cataloguedownloads'
}]
Controller:
init : function() {
this.control({
// reference to the text field in the view
'#SearchDownload' :{
change: this.SearchDownloads
}
});
SearchDownloads : function(){
console.log('Search functionality')
}
UPDATE 1: i was able to get hold of the listener after three characters have been entered using the below code:
Controller
'#SearchDownload' :{
keyup : this.handleonChange,
},
handleonChange : function(textfield, e, eOpts){
if(textfield.getValue().length > 3){
console.log('Three');
}
}
any guidance or examples on how to perform the search in the store of the data view would be appreciated.
A proper way would be to subscribe yourself to the change event of the field and check if the new value has at least 3 chars before proceeding.
'#SearchDownload' :{ change: this.handleonChange }
// othoer code
handleonChange : function(textfield, newValue, oldValue, eOpts ){
if(newValue.length >= 3){
console.log('Three');
}
}
Btw. I recommend you to use lowercase and '-' separated names for id's. In your case
itemId : 'search-download'
Edit apply the filter
To apply the filter I would use filter I guess you now the field you want to filter on? Lets pretend store is a variable within your controller than you may replace the console.log() with
this.store.filter('YourFieldName', newValue);
Second param can also be a regex using the value like in the example
this.store.filter('YourFieldName', new RegExp("/\"+newValue+"$/") );
For sure you can also use a Function
this.store.filter({filterFn: function(rec) { return rec.get("YourFieldName") > 10; }});
Thanks you so much sra for your answers. Here is what i did, based on your comments
filterDownloads : function(val, filterWh){
if(filterWh == 1){
var store = Ext.getStore('CatalogueDownloads');
store.clearFilter();
store.filterBy(function (r){
var retval = false;
var rv = r.get('title');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
if(!retval){
var rv = r.get('shortD');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
}
if(retval){
return true;
}
return retval;
})
}
}
i think there is an example of exactly what you are trying to achive .. http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html
I use form.fields from EXTJS API. My application is totally dynamically.
It is possible to autosize combobox thanks to value which are on store ?
Or i need to make my own method... ?!
Actually, my combobox , is declared as following :
itemId : 'materialid',
xtype : 'combobox',
anchor : '35%',
store : materialstore,
id : 'Material',
queryMode: 'local',
displayField: 'data',
width : 50,
valueField: 'data',
editable : false,
grow : true,
enforceMaxLength : true,
listeners : {
render : function(me){
var obj = materialstore.findRecord('data',materialdefaultvalue);
me.setValue(obj.get('data'),obj);
}
},
padding : '0 30 0 30',
fieldLabel : 'Material',
name : 'material',
listeners : {
blur : function(me){
var fieldvalue = me.getValue();
var sel = monPretree.getView().getSelectedRecords();
for ( var i = 0 ; i < sel.length ; i++){
alert(sel[i].get('id') + ' && ' + material);
}
}
}
Thanks :)
Unfortunately not. Your best bet would be either to set a fixed width (like you have) or set it to '100%'.
A quick note for future questions: it is better to ask them over on the Sencha forums, as you will get a quicker response.
How to group header like grid below in extjs:
|-------------- A1 header------------|--------------B1 Header---------------|
|----A2Header---|---A3Header---|----B2Header---|---B3Header------|
|-----A2Data------|----A3 Data------|-----B2 Data------|-----B3 Data-------|
|-----A2Data------|----A3 Data------|-----B2 Data------|-----B3 Data-------|
my code extjs:
plColModel = new Ext.grid.ColumnModel([
new Ext.grid.RowNumberer(),
{ header: "A2Header", dataIndex: 'A2Data' },
{ header: "A3Header", dataIndex: 'A3Data' },
{ header: "B2Header", dataIndex: 'B2Data' },
{ header: "B3Header", dataIndex: 'B3Data' }
]);
I remember how I've spend a lot of time trying to understand the code in the example Sencha provided for ColumnHeaderGroup. I've made a 6-level column group header several days ago and it is not that difficult.
Put all of your column headers in an object as object keys for the following headers. Last headers' followers will be the columns' properties:
var chstructure = {
'A1 header' : {
'A2Header' : {'A2Data' : {'A2Data' : {'dataIndex' : 'A2', 'width' : 100}}},
'A3Header' : {'A3Data' : {'A3Data' : {'dataIndex' : 'A3', 'width' : 100}}}
},
'B1 header' : {
'B2Header' : {'B2Data' : {'B2Data' : {'dataIndex' : 'B2', 'width' : 100}}},
'B3Header' : {'B3Data' : {'B3Data' : {'dataIndex' : 'B3', 'width' : 100}}}
}
};
You'll need some arrays to put the headers in: these arrays will be the rows in your column header group. You'll also need a fields array: it will contain the fields for your store. Don't forget to initialize some colspan variables (I'll name them len n ) that will keep count of the colspan for each column header (in this example 'A1 header' has 2 children and 'A2Header' has only 1), and some width variables (wid n ), for each header's width.
var Row1contents = [], Row2contents = [], Row3contents = [], Row4contents = [];
var len1 = 0, len2 = 0, len3=0, wid1 = 0, wid2 = 0, wid3 = 0;
var fields = [];
Now you may finally parse chstructure in order to retrieve the column headers. Use Ext.iterate for that:
Ext.iterate (chstructure, function(Row1, Row1structure){
Ext.iterate (Row1structure, function(Row2, Row2structure){
Ext.iterate (Row2structure, function(Row3, Row3structure){
Ext.iterate (Row3contents, function(Row4, Row4structure){
len1++;len2++;len3++;
wid1+=Row4structure['width'];
wid2+=Row4structure['width'];
wid3+=Row4structure['width'];
Row4contents.push({
dataIndex: Row4structure['dataIndex'],
header: Row4,
width: Row4structure['width']
});
fields.push({
type: 'int', // may be 'string'
name: Row4structure['dataIndex']
});
});
Row3contents.push({
header: Row3,
width: wid3,
colspan: len3
});
len3=wid3=0;
});
Row2contents.push({
header: Row2,
width: wid2,
colspan: len2
});
len2=wid2=0;
});
Row1contents.push({
header: Row1,
width: wid1,
colspan: len1
});
len1=wid1=0;
});
View the 4 arrays in your console and ensure they contain all data you set. The last step is to configure the grid width the ColumnHeaderGroup plugin. Use property
plugins: [new Ext.ux.grid.ColumnHeaderGroup({
rows: [Row1Group, Row2Group, Row3Group]
});
Set columns : Row4contents for your grid and fields : fields for your grid's store.
Happy coding!
refer this :
ColumnHeaderGroup
Here is one great example by Sencha
http://dev.sencha.com/deploy/ext-3.4.0/examples/pivotgrid/people.html