How to render more than X elements in react? (Performance) - html

I have a huge component that can receive a start and end date, plus some floors numbers, and based on these numbers, it generates a table, something like the below image.
Example of this table:
The problem is, how to make this table generate faster?
To generate the floors I use a for a loop.
JavaScript code:
for (let i = 0; i < section.floorQuantity; i++) {
floors.push(i + 1)
}
and for each day, I generate a column with the number of floors as cells (divs).

you can use "useMemo" to cache the same computation and it's result change when input data changes
const computeExpensiveValue=(inputs)=>{
//do something
return result
}
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Related

Angular: Posting Data to a Table with a loop and giving a problem when posting the i of the loop into the table

Good day,
I am trying to get data into a table, with the tour_id and every single media_id (the station_id i am getting from somewhere else), the ordernumber is what is giving me a headache:
I am trying to get every station one number for every media i am posting.
For example:
station 1 has 2 medias
and station 2 has 3
then the odernumbers should be like this: 0, 0, 1, 1, 1
I am using the following Code at this moment:
for(var i = 0; i < this.currentStations.length; i++){
this.http.get("http://localhost:3000/mediasforstation/" + this.currentStations[i].id).subscribe((res) => {
medias = res;
for (var j = 0; j < medias.length; j++){
this.http.post("http://localhost:3000/posttourstations",
{"tour_id": id, "media_id": medias[j].id, "ordernumber": i}).subscribe(function(res) {
console.log(res);
}.bind(this));
}
});
}
Everything but the ordernumber works, however, the ordernumber always takes the number of stations involved, in our example above it would be 2.
How do I fix this?
Thank you very much for your help.
As I understand, you need to keep the index value. The type of variable i is var which is function scoped. Within outer loop, you are calling an API that returns some response, meanwhile the value of i is updated and for next index/counter, the API call has been sent. When you get response from API calls, you get the value of i where the outer loop has been called of.
In other words, you need to understand the difference between var and let. Your problem can be solved by replacing
for(var i=0;...)
with
for(let i=0;...)
Here's providing you the sample code.
//block scoped - retains value of i
for (let i=0;i<10;i++){
this.http.get('https://jsonplaceholder.typicode.com/users').subscribe(res=>{
for(var j=0;j<5;j++){
console.log(`i=>${i}`)
}
})
}
//function scoped - gets updated value of i
for (var i=0;i<10;i++){
http.get('https://jsonplaceholder.typicode.com/users').subscribe(res=>{
for(var j=0;j<5;j++){
console.log(`i=>${i}`)
}
})
}

How to programmatically reorder a column in primefaces datatable

I have a datatable with 10 columns which are grouped in 4:4:2 manner. Now the first two groups(of 4) are fixed while the last 2 can be added to any of the groups(single or both at a time) based on a condition.
Is there a way to set indexes for columns so that they can be ordered based on a condition ?
I see that Primefaces reorder using drag n drop gives the kind of result Im looking for except I want the reordering to be programmable and set before the table is displayed.
I had basically the same problem: after allowing the user to rearrange columns, it is easy to save the arrangement into a cookie, but how to restore the order a day later?
As far as I know, there are no primefaces method to this but can be hacked with a little javascript. (I tried with primefaces 6.0)
1) Give all the columns unique styleClasses, like:
styleClass="mystyle col0"
styleClass="mystyle col1"
styleClass="mystyle col2"
...
2) Convert the styleClass strings into valid css selectors, and store the required order of columns as an order of those, like:
".mystyle.col2,.mystyle.col0,.mystyle.col1"
Put it into a cookie, or store and get back as you like.
3) Write a javascript function to rearrange the cells into the required order:
function reorder() {
var o = getCookie('orderString');
var a = o.split(",");
for (var i = a.length - 1; i >= 0; i--) {
$(a[i]).each(function() {
$(this).prependTo($(this).parent())
});
}
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length === 2)
return parts.pop().split(";").shift();
}
(Don't use EL expressions to get back the order string from a backing bean, because it evaluates on page render, so won't update if the user rearranges the columns again.)
4) Execute reorder() "every time you need it".
You'll certainly need it on page loads:
$(document).ready(function() {
reorder();
});
but also on paging events, so add something like this:
<p:ajax event="page" oncomplete="reorder();" />
(And perhaps other times I've not met yet.)

dc.js crossfilter without reduce

Is crossfilter manipulating my data?
Background
I have performed all the processing I need server side and just want to graph exactly what comes down the json pipe. So far I've get the graph working exactly how I want it to except for it seems my data is being manipulated.
Here's my crossfilter code:
ndx = crossfilter(rData);
runDimension = ndx.dimension(function (d) { return [+d.series, +d.norm_1]; });
runGroup = runDimension.group();
runGroup.reduceSum(function (d) { return d.value;});
Note: norm_1 is unique
Issues
Basically I'm noticing two issues:
I know for a fact that all my data will be between -1 and 1 (I've run several checks to test this), BUT when graphing it I see it dips down to -1.4 in some places.
My server sends exactly 1000 rows of data, but by breakpointing some of the dc.js code I can see it's only graphing 752 rows.
More Evidence
On my chart I've set the valueAccessor and added some checks to test the values going out of bounds, and I can see very clearly it goes out:
.valueAccessor(function (d) {
if (d.value > 1 || d.value < -1) {
console.log(d);
}
return d.value;
})
The data from the server requires a small amount formatting before going into crossfilter (it comes down as a table and needs to be split into series objects). I used this as an opportunity to test whether the data goes out of bounds, and I can see clearly it stays within bounds:
for (var i = 0; i < $scope.remoteData.rows.length; i++) {
for (var j = 0; j < $scope.remoteData.labels.length; j++) {
var label = $scope.remoteData.labels[j];
var value = $scope.remoteData.rows[i][label];
if (value > 1 || value < -1) {
console.log({
label: label,
i: i,
series: j,
norm_1: $scope.remoteData.rows[i].norm_1,
value: value,
});
}
rData.push({
series: j,
norm_1: $scope.remoteData.rows[i].norm_1,
value: value
})
}
}
Discussion
I suspect my problems have something to do with:
runGroup.reduceSum(function (d) { return d.value;});
Is this function adding together certain data points?
Sounds like you have some rows for which [+d.series, +d.norm_1] is not unique. And yes any rows with the same key will be added with reduceSum.
I'd suggest making your dimension key be something that's really unique.
If you don't have a unique key, with a little more work you could use the array indices themselves as the dimension key. It will mean you have to use both key and value accessors everywhere to look back in the original array.
Something like:
ndx = crossfilter(d3.range(0, rData.length));
runDimension = ndx.dimension(function(d) { return d; })
runGroup = runDimension.group().reduceSum(function(d) {
return rData[d].value;
})
chart.keyAccessor(function(kv) { return rData[kv.key].x; })
.valueAccessor(function(kv) { return rData[kv.key].y; })

Razor: adding dynamic values together

I have a set of values that are generated dynamically with a foreach loop, how can I add these into one value?
For instance, say I have a site where each node has a number associated with it. How can I add all these numbers together? So far I've figured it'd be something similar to the following, where the value of 'node.aNumberValue' is added to the next one, and so on:
#foreach (var x in nodes){
var total = node.aNumberValue + node.aNumberValue (etc...);
<p>#total</p>
}
This is what you want, I think:
int total = 0;
#foreach (var x in nodes)
{
total += x.aNumberValue;
}
<p>#total</p>
Or even better, just:
<p>#nodes.Sum(x => x.aNumberValue)</p>

How to sort var length ids (composite string + numeric)?

I have a MySQL database whose keys are of this type:
A_10
A_10A
A_10B
A_101
QAb801
QAc5
QAc25
QAd2993
I would like them to sort first by the alpha portion, then by the numeric portion, just like above. I would like this to be the default sorting of this column.
1) how can I sort as specified above, i.e. write a MySQL function?
2) how can I set this column to use the sorting routine by default?
some constraints that might be helpful: the numeric portion of my ID's never exceeds 100,000. I use this fact in some javascript code to convert my ID's to strings concatenating the non-numeric portion with the (number + 1,000,000). (At the time I had not noticed the variations/subparts as above such as A_10A, A_10B, so I'll have to revamp that part of my code.)
The best way to achieve what you want is to store each part in its own column, and I would strongly recommend to change table structure. If it's impossible, you can try the following:
Create 3 UDFs which returns prefix, numeric part, and postfix of your string. For a better performance they should be native (Mysql, as any other RDMS, is not really good in complex string parsing). Then you can call these functions in ORDER BY clause or in trigger body which validates your column. In any case, it will work slower than if you create 3 columns.
No simple answer that I know of. I had something similar a while back but had to use jQuery to sort it. So what I did was first get the output into an javascript array. Then you may want to insert a zero padding to your numbers. Separate the Alpha from Nummerics using a regex, then reassemble the array:
var zarr = new Array();
for(var i=0; i<val.length; i++){
var chunk = val[i].match(/(\d+|[^\d]+)/g).join(',');
var chunks = chunk.split(",");
for(var s=0; s<chunks.length; s++){
if(isNaN(chunks[s]) == true)
zarr.push(chunks[s]);
else
zarr.push(zeroPad(chunks[s], 5));
}
}
function zeroPad(num,count){
var numZeropad = num + '';
while(numZeropad.length < count) {
numZeropad = "0" + numZeropad;
}
return numZeropad;
}
You'll end up with an array like this:
A_00100
QAb00801
QAc00005
QAc00025
QAd02993
Then you can do a natural sort. I know you may want to do it through straight MySQL but I am not to sure if it does natural sorting.
Good luck!