How to make react-virtualized Grid responsive? - responsive-design

I am using the Grid component of react-virtualized, which expects column count and column width as required props. Right now, I am explicitly calculating the screen widths on resizing, and am calculation column width and column count.
My code is as follows:
let gridsNum = this.getColumnCount(this.state.width);
let colWidth = this.state.width / gridsNum;
<Grid
cellRenderer={this.cellRenderer}
columnCount={gridsNum}
columnWidth={colWidth}
height={window.innerHeight}
rowCount={this.state.messages.length}
rowHeight={310}
onScroll={this.onScroll}
width={window.innerWidth}
className="jobs-gridview"
/>
getColumnCount(width){
if(width > 1350){
return 4;
}else if(width > 1000){
return 3;
}else if(width > 650){
return 2;
}else{
return 1;
}
}
I also went through the earlier plunkr example regarding a similar issue: http://plnkr.co/edit/zjCwNeRZ7XtmFp1PDBsc?p=preview.
I apologize for the poor quality of code. Is there anything better I can do to improve Grids for responsiveness?
Thanks.

Related

Efficient Level up after every 10?

I'm trying to make it so that after every say 200 of a value, it will increase a global variable by 1. As you can see below the problem I have is that one, it isn't in any way shape or form efficient and really doesn't work well.
An overall of how I'd like this to work would be so that when GV.TotalNumberValue hits past a certain number, let's say 200, GV.TotalLevel will increase by one and update the text and this will happen every time that GV.TotalNumberValue increases by 200.
Finally, if this is going to be checking what the number is on constantly, should I have this bound to an event such as a button click or a timer? Your help's greatly appreciated, thanks.
void LevelMod()
{
if (GV.TotalNumberValue >= 200)
{
GV.TotalLevel = GV.TotalLevel + 1;
lblLevel.Text = string.Format("{0}{1}", GV.LevelPrefix, GV.TotalLevel);
}
else if (GV.TotalNumberValue >= 400)
{
GV.TotalLevel = GV.TotalLevel + 1;
lblLevel.Text = string.Format("{0}{1}", GV.LevelPrefix, GV.TotalLevel);
}
else
{
return;
}
}
Perhaps use integer division similar to:
void LevelMod()
{
// I assume the level variables are integrals, so perform an integer division
if (GV.TotalNumberValue / 200 > GV.TotalLevel)
{
GV.TotalLevel = GV.TotalNumberValue / 200;
lblLevel.Text = string.Format("{0}{1}", GV.LevelPrefix, GV.TotalLevel);
}
}
Essentially, your TotalLevel is always TotalNumberValue / 200. This assumes that that GV.TotalNumberValue is an integral type which always rounds the result towards zero.
Well, you can use simple math:
Either deduce the level from the value, like this:
int totalLevel = value / 200;
This works because an integer division is always rounded down.
Or, if you know that value has just been incremented, you can detect a level boundary like this:
bool shouldLevelUp = (value % 200) == 0;
if (shouldLevelUp)
++totalLevel;

Creating Range Table

First the thread name might be a little strange but i will try my best to explain what i want to do here so you can suggest me a good thread name.
I want to create a function to return the employee level by checking his experience
If experience is 0~50 he is level 1
If experience is 50~150 he is level 2
... and so on till level 100
What i am thinking of is creating a const int that holds all required exp for each level
public const int Level1 = 50,
Level2 = 150...;
so is there a way to make a function to return what i want ? without the use of 1000++ lines ?!.
Please don't consider my question as a spam i am only very confused and i will try my best to clarify my idea if needed.
int level = Math.Min(10, experience / 10);
Would that do?
If you want to have 0-10 -> 1 and 11-20 -> 2 etc, change it like this:
int level = Math.Min(10, (experience + 9) / 10);
If there is no pattern at all in experience gains, or some very obscure one, you could use this:
var level = 1;
var levelRequirements = new int[] {10, 20, 50, 150, 300};
for (int i = 0; i < levelRequirements.Length; i++)
{
if (levelRequirements[i] > currentExperience)
break;
level++;
}
And now for my final update:
var level = 0;
var levelRequirement = 0;
var levelRequirementAddition = 50;
while (currentExperience >= levelRequirement)
{
levelRequirement += levelRequirementAddition;
levelRequirementAddition += 50;
level++;
}
public int ReturLevel(int experience)
{
return (experience-1)/10 + 1;
}
you may remove the -1 in (experience-1) if you meant "If experience is 1~9"
leave it if you meant "If experience is 11~20 he is level 2"
Edit:
IF your experience to level function doesn't follow any pattern, than Yes, you'll have to make a separate case for each one of them.
if(experience > 20)
return level 3;
else if(experience > 10)
return level 2;
else
return level 1;
different design patterns can affect how and were you add these different cases, but they'll have to be added if you have no pattern.
Since the formula for the xp required for the level x seems to be 25*(x²+x)
You can use the inverse function :
public int GetLevel(int xp)
{
return (int)(Math.Sqrt(1 + 4 * xp / 25) - 1) / 2;
}

else statement not triggering

I have been attempting to create an if else statement that will return a text string based on certain constraints. The first 3 constraints work, but when the event of the final constraint occurs, it triggers the second again. The random number generator occasionally used a 0 value, so I wanted to account for that. I am new to this, and apologize for indenting, etc.
I have been looking around here for a bit and couldn't find anything that seemed to cover this. If I missed it, a hint in the right direction would be appreciated as well.
double txtestimateCategory = [mynum computeVolume];
NSLog(#"The volume is %f", txtestimateCategory);
int v = ((txtestimateCategory * 1));
if ((v >= 8000))
{
NSLog(#"The box is large");
}
else if ((1 <= v < 1000))
{
NSLog(#"The box is small");
}
else if ((1000 <= v < 8000))
{
NSLog(#"The box is medium");
}
else
{
NSLog(#"The box is a lie");
}
Comparators are binary operators. You have to write:
else if (1 <= v && v < 1000)
etc.
(Otherwise you would be evaluating things like true < 1000, and true converts to 1 implicitly. Not what you meant!)

Performing Calculation on Filtered DataGridView

I have a Datagridview which I populate from a Dataset created from an XML file. This part works and I can get the entire contents of the Dataset to display in a datagrid. I have the added functionality to filter the datagridview based upon a date and sold flag. This also works OK as the datagridview updates as you cycle through the dates. However I need to do some calculations on the "filtered" datagridview. These calculations are need to convert various currencies into GBP. So after some research on the best way to do this I decided to loop through the visible datagridview and test each of the visible. This is the code I cam up with. Unfortunately when run it all the tests fail and it try to carry out the else clause which then fails with a "Input string was not in a correct format" Exception. However I do not think that is the issue as I put a watch on the Price and Currency values and they "Do not Exist in the current Context"...now im stuck and would appreciate some help. Perhaps im going about this wrong way...
Thanks
Harry
for (int i = 1; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1["currency", i].ToString() == "USD")
{
myCommission += double.Parse(dataGridView1["commission", i].ToString()) * (double.Parse(dataGridView1["price", i].ToString()) * UStoGB);
}
else if (dataGridView1["currency", i].ToString() == "EURO")
{
myCommission += double.Parse(dataGridView1["commission", i].ToString()) * (double.Parse(dataGridView1["price", i].ToString()) * EUtoGB);
}
else
{
myCommission += double.Parse(dataGridView1["commission", i].ToString()) * double.Parse(dataGridView1["price", i].ToString());
}
}
I managed to get this working using
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells["currency"].FormattedValue.ToString() == "USD")
{
string tempval = dataGridView1.Rows[i].Cells["commission"].ToString();
myCommission += double.Parse(dataGridView1.Rows[i].Cells["commission"].FormattedValue.ToString()) * (double.Parse(dataGridView1.Rows[i].Cells["price"].FormattedValue.ToString()) * UStoGB);
}
else if (dataGridView1.Rows[i].Cells["currency"].FormattedValue.ToString() == "EURO")
{
myCommission += double.Parse(dataGridView1.Rows[i].Cells["commission"].FormattedValue.ToString()) * (double.Parse(dataGridView1.Rows[i].Cells["price"].FormattedValue.ToString()) * EUtoGB);
}
else
{
myCommission += double.Parse(dataGridView1.Rows[i].Cells["commission"].FormattedValue.ToString()) * (double.Parse(dataGridView1.Rows[i].Cells["price"].FormattedValue.ToString()));
}
}
seems that without the FormattedValue parameter it and specifying Rows[i] and Cells[i] it just wasn't getting to the values. Also needed to disable the allowusertoaddrows functionality so it wouldn't count the last line. This is not a problem as it is readonly.
Mohgerth thanks for your reply will look replacing the for...else section with a case now its working as
A little alterations with some notes:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
switch (row["currency"].ToString())
{
case "USD":
myCommission += double.Parse(row["commission"].ToString()) * (double.Parse(row["price"].ToString()) * UStoGB);
break;
case "EURO":
myCommission += double.Parse(row["commission"].ToString()) * (double.Parse(row["price"].ToString()) * EUtoGB);
break;
case else:
myCommission += double.Parse(row["commission"].ToString()) *(double.Parse(row["price"].ToString());
break;
}
}
Not that this is any better of an answer, but changing this to a foreach will allow you to put a watch on row to determine what the exact names of the columns are. The column names may be case sensative or the XML import may have done something to the name of the column.
Either way being able to put a breakpoint in and look at the value of row cells

Area constraint blows up my physics simulation if a body slams into it too fast

I have a physics simulation and it allows you to place area constraints, so that the bodies within will not exit that area. However if an atom goes past one of the "walls" of the area constraint it blows up the physics simulation. Why does it do this?
Update method:
if (!atom.IsStatic)
{
Vector2 force = Vector2.Zero;
bool x = false, y = false;
if (atom.Position.X - atom.Radius < _min.X)
{
force = new Vector2(-(_min.X - atom.Position.X), 0);
if (atom.Velocity.X < 0)
x = true;
}
if (atom.Position.X + atom.Radius > _max.X)
{
force = new Vector2(atom.Position.X - _max.X, 0);
if (atom.Velocity.X > 0)
x = true;
}
if (atom.Position.Y - atom.Radius < _min.Y)
{
force = new Vector2(0, -(_min.Y - atom.Position.Y));
if (atom.Velocity.Y < 0)
y = true;
}
if (atom.Position.Y + atom.Radius > _max.Y)
{
force = new Vector2(0, atom.Position.Y - _max.Y);
if (atom.Velocity.Y > 0)
y = true;
}
atom.ReverseVelocityDirection(x, y);
if (!atom.IsStatic)
{
atom.Position += force;
}
}
I see you're doing calculation with a constant time step T. When modeling collisions though on every step you should use time step equal to minimal time before any of atoms reach any obstacle.
Make time step variable, and atoms will never "tunnel" obstacles.
P.S. There are a lot of optimizations in collision detection, please read gamedev papers for information on those.
P.S. A bug?
force = new Vector2(-(_min.X - atom.Position.X), 0);
Force is created separately for X and Y reflection. What happens when the atom gets into a corner? Only second force will be applied.
P.P.S: Use epsilon
One more important note: if you use floating point, the error is accumulated, and you should use eps:
abs(atom.Position.Y + atom.Radium - _max.Y) < eps
where eps is a number much smaller than normal sizes in your task, e.g. 0.000001.
You seem to have solved the problem already, but I notice that "force" seems to be wrong. It moves the atom away from the boundary, even if it's on the wrong side. Suppose an atom has shot past _max.X:
if (atom.Position.X + atom.Radius > _max.X)
{
force = new Vector2(atom.Position.X - _max.X, 0);
...
}
Now "force" will be in the +x direction, and the atom's distance from the wall will double with every iteration. Boom!
Wouldn't you know, after about half an hour of mindless hacking at it, i thought of simply not applying the position correction. That fixed it like a charm. For any interested, here's the updated code:
if (!atom.IsStatic)
{
if (atom.Position.X - atom.Radius < _min.X && atom.Velocity.X < 0)
{
atom.ReverseVelocityDirection(true, false);
}
if (atom.Position.X + atom.Radius > _max.X && atom.Velocity.X > 0)
{
atom.ReverseVelocityDirection(true, false);
}
if (atom.Position.Y - atom.Radius < _min.Y && atom.Velocity.Y < 0)
{
atom.ReverseVelocityDirection(false, true);
}
if (atom.Position.Y + atom.Radius > _max.Y && atom.Velocity.Y > 0)
{
atom.ReverseVelocityDirection(false, true);
}
}

Resources