Creating dynamic columns in an Ext JS Grid - extjs

I am looking to create some logic for JSON data retrieved from a server request. As you can see from the raw data below, it is received in a particular format.
There is a "balances" entry which, in this case, has 5 different sub-values, of which names can vary dependent upon a given user.
For example:
Barry has 5 bank accounts, each with different balances.
Melissa has 2 bank accounts, each with different balances.
Melissa's bank accounts are different to Barry's bank accounts, and vise versa.
The Balance ID numbers that are assigned, may not necessarily match both Barry and Melissa.
In the Ext JS grid, the column headings which need to be displayed, must adjust to both Barry and Melissa's individual bank account balances.
Barry's JSON Data:
{
"firstName": "Foo",
"lastName": "Bar",
"balances":
{
Natwest: 9,
BankofScotland: 2,
Lloyds: 40,
Halifax: 89,
Lords: 12
},
}
Melissa's JSON Data:
{
"firstName": "Melissa",
"lastName": "Bar",
"balances":
{
DifferentNatwest: 10,
DiffferentBankofScotland: 45
},
}
At the moment, I only have one mapping in my store/model, called "balances" which only takes one value:
Store/Model definitions:
fields: ['firstName', 'lastName', 'balances']
So, obviously the following issue occurs when the grid is generated, as more than one value is being passed:
Results:
The Question:
Does anyone know what I can do to get the columns to dynamically generate in this Ext JS grid, dependant upon the JSON data being received for this balances information?

What you need is to create the grid columns and store for it dynamically.
I don't know if there is some more "ExtJS" way (simpler, automatic creation) but I would do a straightforward solution.
1# Solution - with multiple columns
Get the data, get the JSON object
Based on the JSON object create the new grid columns
Based on the JSON object create the new store with correct records (I
don't think there is model which can have object in it - you need to transofrm it)
Create the grid and add the new store and columns to it.
Here is the code snippet with the most important part:
for (var key in d.balances) {
bankAcountsColumns.push({
xtype: 'gridcolumn',
dataIndex: key,
text: key
});
transformData[key] = d.balances[key];
fields.push(key);
}
var myCustomColumns = [{
xtype: 'gridcolumn',
dataIndex: 'firstName',
text: 'Name'
}, {
xtype: 'gridcolumn',
dataIndex: 'lastName',
text: 'LastName '
}, {
xtype: 'gridcolumn',
text: 'Bank accounts',
columns: bankAcountsColumns
}]
Ext.create('MyApp.view.MyGridPanel', {
renderTo: Ext.getBody(),
columns: myCustomColumns,
store: {
fields: fields,
data: transformData
}
});
Here is working fiddle example:
https://fiddle.sencha.com/#view/editor&fiddle/1l5j
2# Solution - one column
If you want to have only one column with all the balances, you would need templatecolumn
In there I would create template for 5 items (or it can be again created dynamically):
tpl:'{bank1name} {bank1value} {bank2name} {bank2value} ...'
And than you would have to dynamically create the data for the new store.
data:[
{ firstName: "Foo", lastName:"Scott", bank1name: "Natwest", bank1value: "9" ... },
{ firstname: "Dwight", lastName: "Bar", ... bank5name: "" ... }
]

Related

How to get my array object into a material ui table

I have an array that I want to get inside a material ui table. This is the structure of my array, which is taken from a file that I import (using react papa parse 3):
https://react-papaparse.js.org/
This is a link to the code I am trying to get the data into:
https://codesandbox.io/s/htvjz?file=/demo.js
I am a bit confused on the structure of the array, being relatively new at this. Does my row data go one extra level deep with the "data" level in there?
How can I get this into the material ui array table linked to above?
Spent all day on this and going round and round in circles.
the link you show uses table. That closely resembles an HTML table.
I can recommend using a instead. It's easier to read, faster to write, it's more powerful.
import * as React from 'react';
import { DataGrid } from '#material-ui/data-grid';
// define which columns you have in your data
const columns = [
{ field: 'id', headerName: 'ID' },
{ field: 'firstName', headerName: 'First name' },
{ field: 'lastName', headerName: 'Last name' },
];
// your rows.. you probably won't hard code them but get them from elsewhere
// but they should look like this:
const rows = [
{ id: 1, lastName: 'Snow', firstName: 'Jon'},
{ id: 2, lastName: 'Lannister', firstName: 'Cersei'},
{ id: 3, lastName: 'Lannister', firstName: 'Jaime' },
{ id: 4, lastName: 'Stark', firstName: 'Arya' }
];
...
// Then, wherever you want to have your grid, do this:
<DataGrid rows={rows} columns={columns} />

From Google Sheets into React Grid

How can I do in REACT if I want to connect Google Sheets as a remote source into React Grid (from DevEstreme)?
Well, DevExtream Reactive Grid can work with data only in the following format:
<Grid
rows={[
{ id: 0, product: 'DevExtreme', owner: 'DevExpress' },
{ id: 1, product: 'DevExtreme Reactive', owner: 'DevExpress' },
]}
columns={[
{ name: 'id', title: 'ID' },
{ name: 'product', title: 'Product' },
{ name: 'owner', title: 'Owner' },
]}>
<Table />
</Grid>
You need to associate a column with a row field using the column’s name field. It means that if you could get data from your Google Sheet (e.g. as in Google Sheets API - Reading and Writing Values) and modify them according to this, you will be able to display them.
If you need an automatical connection, the answer is no. Reactive Grid accepts only this data format. Otherwise, you need to process data manually.

sencha extjs store hasmany iteration is slow

I have a serious performance problem updating records through a hasMany relation. (using sencha extjs 4.0)
Suppose we have a model with a hasMany relation. I'll rewrite my actual stuff in a simplified model based on sports teams and their players.
Ext.define('project.model.Team', {
extend: 'Ext.data.Model'
, fields: [
{name: 'id', type: 'int'}
, {name: 'name', type: 'string'}
]
, hasMany: [
{ model: 'project.model.Player', name: 'players' }
]
});
Ext.define('project.model.Player', {
extend: 'Ext.data.Model'
, fields: [
{name: 'id', type: 'int'}
, {name: 'team_id', type: 'int'}
, {name: 'name', type: 'string'}
, {name: 'attribute', type: 'int'}
]
, associations: [
{ type: 'belongsTo', model: 'project.model.Team', foreignKey: 'team_id', primaryKey: 'id' }
]
});
Suppose there are a lot of teams and a lot of players, but we want to update something on each player in a specific team. Maybe the team played a game, so we add one game played. Details not important.
This was the working code. It wasn't a problem until someone had a "team" with a lot of "players" in an already pretty large database. This loop takes forever at a fairly modest size. I think set is triggering extra checks on every iteration, instead of just setDirty.
teamStore.getById(record.get('item_id')).players().each(function(player) {
var player_instance = exceptionStore.getById(exception.get('id'));
player_instance.set('attribute', value);
});
playerStore.sync();
This runs really quickly, sets the attribute on the reference object, and does NOTHING.
teamStore.getById(record.get('item_id')).players().each(function(player) {
player.set('attribute', value);
});
teamStore.sync();
playerStore.sync();
I think that code doesn't work because the players are just some sort of reference with no info other than their id in the player store, but they are not actually connected to the store in any way.
Is there some faster way to get the players associated with a team, and actually do something?
You need to put the store in batch update mode with suspendEvents, so it queues up all the changes, rather than try to do all the internal bookkeeping one-at-a-time during your loop. Once you are done changing it, let it catch up in resumeEvents.
https://docs.sencha.com/extjs/4.0.7/#!/api/Ext.data.Store-method-suspendEvents
playerStore.suspendEvents();
playerStore.query('team_id', team_id).each(function(player){
player.set('attribute', value);
});
playerStore.resumeEvents();
playerStore.sync();

Using Highcharts display donut hightchart having dynamic data

I am new to the highcharts. I am using donut highchart where in the below provided link we can get the static data
http://jsfiddle.net/gh/get/jquery/3.1.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/3d-pie-donut/
But i have a no. of data in the same format as
Highcharts.chart('container5',{
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45
}
},
title: {
text: 'Daily Report'
},
subtitle: {
text: '3D donut'
},
plotOptions: {
pie: {
innerSize: 100,
depth: 45
}
},
series: [{
name: 'Amount',
data: [$rootScope.oprep2]
}]
})
Here $rootScope.oprep2 is the data which in the array format as per the format shown / given in the demo as
in the above picture you can the line number 1025 which is in the required format.
the above pic shows the open array which contains data as unitno and amountpaid
My Query is, that the data is not displaying in the chart. So any idea, which will help me a lot. Here is the view as daily report
Here is my data
Array[11] =>
Array[2]=>
0:"001"
1:180
Array[2]=>
0:"007"
1:4570
Array[2]=>
0:"008"
1:1060
Array[2]=>
0:"026"
1:180
Each array is seperated by ,
As i have gone through your code, i see that your getting array of array, but you are assigning that data again with array which is not getting the chart. Instead of joining, separation, try to remove the array assign it directly.
data:$rootScope.oprep2
but not
data:[$rootScope.oprep2]

Why is ng-grid not sorting by both columns?

I have 2 grids showing the same data with 2 different sorts:
$scope.aGridOptions = {
data: 'aData',
columnDefs: [
{ displayName: 'Column 1', field: 'col1',},
{ displayName: 'Column2', field: 'col2',}],
sortInfo: {
fields: ['col1'], directions: ['asc']
},
};
$scope.bGridOptions = {
data: 'aData',
columnDefs: [
{ displayName: 'Column 1', field: 'col1',},
{ displayName: 'Column2', field: 'col2',}],
sortInfo: {
fields: ['col1', 'col2'],
directions: ['asc', 'asc']
},
};
As the plunker shows, both sort the same way, only by column 1. Not only that, but ng-grid 2.0.7, trashes by sortInfo object on bGridOptions to shorten the sort to only one column.
http://plnkr.co/edit/riDzDcS3YSJrQrULwL2j?p=preview
I can't seem to find where it is destroying my sort options. How do I get it to sort by 2 columns and not have it trash my sortInfo?
Below is the initial answer I typed, which seemed to work as I played around in your Plunk; however, when I went to make a clean copy of the Plunk it stopped working. It sounds like this issue may be resolved in 2.0.8 though, see Issue #748 and Issue #732.
My initial response, but not working for me now...
Try changing the sortInfo for each grid to look like this:
$scope.aGridOptions.sortInfo = {
fields: ['col1'],
directions: ['asc'],
columns: [0]
};
$scope.bGridOptions.sortInfo = {
fields: ['col1', 'col2'],
directions: ['asc', 'asc'],
columns: [0, 1]
};

Resources