extjs 4 line chart rendering problems - extjs

I am having trouble with extjs rendering the line chart below. Specifically, the last six values are null which are (correctly) not shown on the series line but (incorrectly) have a marker dot displayed for them (see top right of the image below).
I am pulling the graph data from a database as json:
// data store fields
Ext.define('Graphs', {
extend: 'Ext.data.Model',
fields: [
{name: 'the_quota', type: 'int'},
{name: 'count_pt_year', type: 'int'},
{name: 'date_string', type: 'string'}
]
});
// get the graph data
var graphStore = Ext.create('Ext.data.Store', {
model: 'Graphs',
proxy: {
type: 'ajax',
url: 'sqlRequest.jsp?queryName=events_getGraph',
timeout: 160000,
reader: 'json'
},
autoLoad:false
});
If I change the query to return these null values as blanks instead ('') then the json reader converts them to zeros and the values display as zero along the bottom of the graph with a series line, which is worse then having the markers plastered to the ceiling without a series line.
I haven't been able to find any config option in Ext.chart.Series to hide null values on the graph. Nor have I been able to find a config option in Ext.data.Store to return blanks as blanks and not "0".
Looking for some other workaround.
Or has anyone resolved these issues from within the library itself (ext-all.js)?

There's a config option under Ext.data.Field called useNull. If the data received cannot be parsed into a number, null will be used instead. As of right now I can't recall if that alone will fix the problem, and I have a memory of once using a custom convert function that went something like this:
convert: function(value){
if(typeof value !=== 'number') // or other similar conversion
return undefined;
return value;
}
If this doesn't work, you may need to customize your store/reader to completely exclude records containing the undesirable null value.
EDIT - Using useNull looks like this: {name: 'someName', type: 'int', useNull: true}

Related

ExtJs 6 - change in ajax update requests

ExtJs does not expect the same response from the server to confirm updating rows than ExtJs 4.
I have a table with a string id:
Ext.define('App.Product', {
extend: 'Ext.data.Model',
fields: [
{name: 'productid', type: 'string'},
{name: 'ord', , type: 'int'},
(...)
],
idProperty: 'nrproduit'
})
Upon saving the changes, the ExtJs client sends the modified data to the server:
[{"ord":1,"productid":"SG30301"},{"ord":3,"productid":"SG30100"}]
In ExtJs 4.2, it expected the server to send the full data of the two products back, like this:
{
"success":true,
"data":[{
"nrproduit":"SG30100",
"ord":3,
"author":"...",
"editor":"...",
(...)
},{
"nrproduit":"SG30301",
"ord":3,
"author":"...",
"editor":"...",
(...)
}]
}
In ExtJs 6.2, this no longer works. I get the error
Uncaught Error: Duplicate newKey "SG30100" for item with oldKey "SG30301"
Apparently, the client does not take into account the idProperty, but seems to expect the order of the row to be the same in the response as in the request.
Is there a way to force the client to take into account the ids sent back from the server ? Or is it necessary to change the server code ? Is there somewhere documentation on what exactly changed between ExtJs 4.2 and 6.2 in respect to data synchronization between client and server, that go into these details ?
ExtJS considers the order because ids can change, e.g. during insert operations (if the id is generated server-side). To allow for that, in the general case, ExtJS expects to receive the results from the server in the same order in which the records were sent.
However, there's more to it. Under certain circumstances, it uses the id, not the order. You can read Operation.doProcess to find how ExtJS does what it does, and possibly override it if you require a different behaviour.
Edit: It uses the id when the model has the property clientIdProperty, else it uses the order. So, it is enough to add it like this:
Ext.define('App.Product', {
extend: 'Ext.data.Model',
fields: [
{name: 'productid', type: 'string'},
{name: 'ord', , type: 'int'},
(...)
],
idProperty: 'nrproduit',
clientIdProperty: 'nrproduit'
})
Another alternative solution, if you don't want to change the server side code to handle the clientIdProperty property is to disable the batch mode (with batchActions: false) and all your requests are handled one by one.
This is prevent the error "extjs Ext.util.Collection.updateKey(): Duplicate newKey for item with oldKey". With his approach, you will loose some efficiency.
You have to add this to your model:
...
proxy: {
type: 'direct',
extraParams: {
defaultTable: '...',
defaultSortColumn: '...',
defaultSordDirection: 'ASC'
},
batchActions: false, // avoid clientIdProperty
api: {
read: 'Server.Util.read',
create: 'Server.Util.create',
update: 'Server.Util.update',
destroy: 'Server.Util.destroy'
},
reader: {
Just adding clientIdProperty on Model definition solved the issue.
Some more info. Same problem has been asked on sencha forum but solution is not mentioned there. Here is the link to that discussion-
https://www.sencha.com/forum/showthread.php?301898-Duplicate-newKey-quot-x-quot-for-item-with-oldKey-quot-xx-quot

How to add value to compare it in xtype

Some help please.
I'm trying to display a xtype depending on value that i get from database.
I have created the store to fetch data from my server side, and it receives only boolean value true or false nothing else.
var hidden= Ext.create('Ext.data.Store',
{
fields: ['hidden'],
autoLoad: true,
proxy:
{
type: 'ajax',
url: 'hidden/compare',
reader:
{
type: 'json',
root: 'data'
}
}
});
Here is the example what i want, but i don't know what to add instead value_from_the_store
text: 'Now you see me, now you don't',
xtype: value_from_the_store == false ? 'hidden' : 'textfield',
If you look at the docs for Ext.data.Store, you'll see several functions that allow you to access the data in the store.
Ext.data.Store
I'm not sure which record you want to access, or if there is only one record, but you can get records by index using getAt, or by ID using getById. You can get the first record using first. There are also several find functions, which allow you to search for a specific record.
Since you said there is only one record, you could just use first. You'll also need to get the specific field in the record using get('hidden').
xtype: hidden.first().get('hidden') ? 'hidden' : 'textfield',
Here, you can try this fiddle - https://fiddle.sencha.com/#fiddle/lho
I've created this fiddle in Ext 5 but you can still make it work in 4. Hope this helps.
Here is the same fiddle for Ext 4.2 - https://fiddle.sencha.com/#fiddle/lji
And in the fiddle, instead of calling the function, you can even do this -
xtype: store.getAt([0]).get('hidden')? 'hidden' : 'textfield'
Another way of fetching the value from the store is by -
store.findRecord('hidden', 'true').get('hidden')
store.findRecord('fieldName', 'Either a string that the field value should begin with, or a RegExp to test against the field.')
Here's your link to the API doc

How come store.add() method does not perform mapping?

I have a nested json data, namely:
{
name: 'alex',
tel: {
personal: '347xxxx',
work: '331xxxx'
}
}
Then the following model:
Ext.define("Employer", {
extend: 'Ext.data.Model',
idProperty: 'personalTel',
fields: [...
{name: 'personalTel', mapping: 'tel.personal'}
Finally the following store:
Ext.create('Ext.data.Store',{
model: 'Employer',
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'root'
}
},
data: myInitialData //an array containing json objects
As long as the data is contained in myInitialData the personalTel field is correctly set.
However, adding a new record to the store does not trigger the mapping and so I find myself with strange personalTel property, that is automatic IDs extjs puts!
ExtJS allows you to load multiple models via nesting when using a reader. It does not allow those models to be created when instantiating the model directly, which is what adding the object to the store does.
The idea is that each model is treated separately with its own store. Want to add a customer with a telephone number? Create the telephone number first, put it in its store, then create the customer with a reference to the telephone number.
This approach is a bit clumsy, though, and only works with models that really are separate entities.
An alternative approach would be to use a custom type, or simply to use the 'auto' type (which treats the data as a blob that you can do what you want with). Both approaches have their drawbacks.

Loading multiple extjs comboboxes in a form

another ComboBox question.
In my table there are about 10 fields that are foreign keys, all presented with comboboxes.
How to fill all this combos in a form, without go 10 times to server to load the store of each one?
Are they stored as separate tables on the back end? If yes, then the correct way would be to load them going to the server 10 separate times. You can optimize this scenario by:
loading them all simultaneously
loading them all before you get to that page in advance
But you still would want to have 10 different stores in your ExtJs application.
If you wish to combine them into single store remember couple things
you would need to add additional field into this combined table so you can distinguish different lists.
you would load them all at once
then you would still need to separate them into different store objects because otherwise different UI components (comboboxes) won't be able to show different sets of data
Well known problem :) Typically when I have structure like this
var data = {
ForeignKeyObjectId: 123,
ForeignKeyObject: {
Id: 123,
SomeValue: 'Some text 1'
},
SomeOtherObjectId: 456,
SomeOtherObject: {
Id: 456,
SomeValue: 'Some text 2'
}
//, ... same 8 times more
}
I have to load each combo manually:
var combo1 = this.down('#foreignKeyObjectCombo');
combo1.setValue(data.ForeignKeyObject.Id);
combo1.setRawValue(data.ForeignKeyObject.SomeValue);
combo1.store.loadData([data.ForeignKeyObject], true);
var combo2 = this.down('#someOtherObjectCombo');
combo2.setValue(data.SomeOtherObject.Id);
combo2.setRawValue(data.SomeOtherObject.SomeValue);
combo2.store.loadData([data.SomeOtherObject], true);
// same 8 times more
In one of my previous projects on ExtJs 3 I made some overrides for form and combobox behaviour so that I could use form.getForm().loadData(data) once instead of manually setting value, rawValue like in this example. But that way was implicit, so I like more this way :)
Example:
Model 1
Ext.create('Ext.data.Store', {
model: 'EmployeeType',
data : [
{type: 1, description: 'Administrative'},
{type: 2, description: 'Operative'},
]
});
Model 2
Ext.create('Ext.data.Store', {
model: 'BloodType',
data : [
{type: 1, description: 'A+'},
{type: 2, description: 'B+'},
]
});
Even if your stores have Proxy, you can disable AutoLoad so you can load as many as you want in one single request like this:
Create the stores manually:
employeeType = Ext.create('Ext.data.Store', {model: EmployeeType});
bloodType = Ext.create('Ext.data.Store', {model: BloddType});
Create an Ajax request where you bring all combos at once:
Ext.ajax.request({
url: './catalogs/getalldata',
success: function(response) {
var json = Ext.decode(response.responseText);
employeeType.loadData(json.employeeTypes);
bloodType.loadData(json.bloodTypes);
//...
}
});

ExtJS GridPanel numberColumn - sort issue

I have a grid Panel with 4 columns, one of these is numeric (number up to 4 digit), and I would like to sort the row by this colum. My problem is Ext JS sorts the rows as if the column was textual, so 5 is sorted after 3000.
I tried to use a numberColumn instead of a normal column (specifying the x-type in the columns of the GridPanel), but it doesn't change the sorting.
Thus I tried to format the numbers so 5 would appear like 0005, and 0005 would be before 3000. But the format options of the numberColumn do not appear to let me specify a minimal number of digit (in Java, using NumberFormat, 0000 would work, but here it doesn't).
So I put a renderer to force my number to appear with 4 digits, it works, but it seems that the sort method use the values before beeing rendered, wich is quite logical.
I'm stuck after trying all my ideas, does anyone have a clue?
If you're using a remote store sort, then the sorting is done remotely (the database, like mysql). So what is the type of column on the database for that field? If it's a char or varchar, then that's the issue.
I've had a similar issue, the column type doesn't fix this. To have a proper ordering the type in model should be numeric.
1) Set your field type as integer in model definition.
Ext.define('myModel', {
extend: 'Ext.data.Model',
fields: [{ name: 'myField', type: 'int' }]
});
2) Create a Store using that model.
var myStore = Ext.create('Ext.data.Store',{
model: 'myModel'
});
3) Define a GridPanel using the store and link your field as dataIndex into columns definition.
Ext.create('Ext.grid.Panel',{
store: myStore,
columns: [{
header: 'Numbers', dataIndex: 'myField'
}]
});
I encountered a similar problem where by exj grids sort by each digit in your number, so for example a list might be reordered to 1, 2, 22, 3, 4, 41, 5... for what its worth, i found in extjs4, that defining the type as int in the model did the trick, I havent specified the local or remote sort but it seems to be working...
Ext.define('ExtMVC.model.Contato', {
extend: 'Ext.data.Model',
fields: [{'id', type: 'int'}, 'name', 'phone', 'email']
});
This is my code that connects to a MySQL. I followed this -> {'id', type: 'int'}, and it work out fine... Thank you all! I'm using Ext js 4.2.x

Resources