PDA

View Full Version : Problems with putting json data into store without proxy (websockets)



kovacsm
25 Oct 2017, 4:06 AM
Hi,

I have a problem with putting json data direct in a data store and showing the data in a d3 heatmap and a chart.

I created a modern project with a tab panel. In one tab I have the heatmap and in the other the line chart. I send the data from a server to the application via websockets. For that I implemented a websocket js client (I use them as a resource in the project). The received data has the following structure (it is a nested json structure in a array).


57131

In my heatmap I want to show the x, y and z values and in the line chart I want to show the x and y values.

For that I created a data store, a model and a js function which puts the data into the store.

Store Heat-Map:


Ext.define('TestingApp.store.heatmap-data-store', {
extend: 'Ext.data.Store',


requires: [
'TestingApp.model.heatmap-model'
],


constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'heatmap-data-store',
autoLoad: true,
model: 'TestingApp.model.heatmap-model'
}, cfg)]);
}
});


Heatmap-Model:


Ext.define('TestingApp.model.heatmap-model', {
extend: 'Ext.data.Model',


requires: [
'Ext.data.field.Field'
],




fields: [
{
name: 'x'
},
{
name: 'y'
},
{
name: 'z'
}
]


});


Store chart:


Ext.define('TestingApp.store.chart-data-store', {
extend: 'Ext.data.Store',


requires: [
'TestingApp.model.chart-model',
'Ext.util.Sorter'
],


constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'chart-data-store',
model: 'TestingApp.model.chart-model',
sorters: {
property: 'x'
}
}, cfg)]);
}
});


Chart Model:


Ext.define('TestingApp.model.chart-model', {
extend: 'Ext.data.Model',


requires: [
'Ext.data.field.Integer'
],




fields: [
{
type: 'int',
name: 'x'
},
{
type: 'int',
name: 'y'
}
]


});


Function to put data into stores:


var addDataToStore = function(message)
{
datasets = JSON.parse(message.data);
console.dir(datasets);


//console.dir(Ext.getCmp('tabPanel').getActiveItem().id);


//***Fill Heatmap-Store***




if(Ext.getCmp('tabPanel').getActiveItem().id == 'heatmapID')
{
var heatmapStore = Ext.StoreMgr.lookup('heatmap-data-store');




heatmapStore.clearData();
console.log('count' + heatmapStore.getCount());


for(var i = 0; i < datasets.length; i++)
{
heatmapStore.add(
{
x: datasets[i].data.x,
y: datasets[i].data.y,
z: datasets[i].data.z


}


);


}


var arrayStore= Ext.StoreMgr.lookup('MyArrayStore');
arrayStore.add(datasets);




console.log('count' + heatmapStore.getCount());






}






//***Fill Chart-Store***
else if (Ext.getCmp('tabPanel').getActiveItem().id == 'chartID')


{




var chartStore = Ext.StoreMgr.lookup('chart-data-store');




chartStore.clearData();
console.log('count datasets in store' + chartStore.getCount());


for(var m = 0; m < datasets.length; m++)
{
chartStore.add(
{
x: datasets[m].data.x,
y: datasets[m].data.y





}


);


}
console.log('count datasets in store' + chartStore.getCount());
}




};


So I put the dataset values into the store with a loop, not the best I think but I have no idea how to do it in a other way.
The number of datasets can vary between 1 and 1.000.000. So My solution works but only for number of datasets smaller than 200 datasets. If I send more datasets and fill the store the application freeze. And now values are rendered....

I want to show up to 500.000 datasets in my heatmap... I think I need a better solution to fill the data in the store and render the data...

Should I change the structure of my model to a nested structure like my json data and put the whole array in the store?? In my heatmap I set the store config to the heatmap store and I did the same for my chart. But how can the axes know where the data are because of the nested structure?

Or are there better solutions to solve this? There are no websocket solutions for stores in extjs...

heatmap and chart:


items: [
{
xtype: 'd3-heatmap',
title: 'Heat-Map',
height: 500,
id: 'heatmapID',
width: 1000,
displayed: true,
padding: '40 30 20 80',
tooltip: {
trackmouse: true,
renderer: 'onSeriesTooltipRenderHeatmap'
},
store: 'heatmap-data-store',
legend: {
docked: 'bottom',
padding: 60,
items: {
count: 11,
slice: [
0
],
reverse: true,
size: {
x: 60,
y: 30
}
}
},
xAxis: {
axis: {
orient: 'bottom'
},
scale: {
type: 'linear'
},
title: {
text: 'X-Values'
},
field: 'x',
step: 1
},
yAxis: {
axis: {
orient: 'left'
},
scale: {
type: 'linear'
},
title: {
text: 'Y-Values'
},
field: 'y',
step: 1
},
colorAxis: {
field: 'z',
minimum: 0,
scale: {
type: 'linear',
range: [
'white',
'green'
]
}
},
interactions: {
type: 'panzoom'
}
},
{
xtype: 'cartesian',
title: 'Line-Chart',
height: 250,
id: 'chartID',
width: 400,
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
legend: {
type: 'sprite',
docked: 'right'
},
store: 'chart-data-store',
axes: [
{
type: 'category',
fields: [
'x'
],
grid: true,
title: 'X-Values',
visibleRange: [
0,
1
]
},
{
type: 'numeric',
fields: [
'y'
],
grid: true,
position: 'left',
title: 'Y-Values'
}
],
series: [
{
type: 'line',
colors: [
'rgba(0,200,0,0.3)'
],
highlight: true,
marker: {
radius: 4
},
style: {
smooth: true,
stroke: 'rgb(0,200,0)',

},
tooltip: {
trackMouse: true,
renderer: 'onSeriesTooltipRenderChart'
},
xField: 'x',
yField: 'y',
fill: true
}
],
interactions: [
{
type: 'crosszoom'
}
]
}
]
},


I hope my problem is described clearly enough....