An Array in which 3 objects represent one Cell in uitableView - iphone

I'm loading data from sql into an NSMutableArray lets say its a table of Entries of Height and Weight each having a timeStamp (NSDate)
So the User enters the height and Weight!
I make a call to the entries to fetch all data sorted by timeStamp, that is the latest is the first.
this is the order i get,
-Height - 30 Jan 2012
-Weight - 30 Jan 2012
-Height - 30 December 2011
-Weight - 30 December 2011
-Height - Novem 2011
-Weight - Novem 2011
So i have 6 objects in my mutableArray.
ALthought in the tableView datasource, I want only 3 rows. Each with the combination of ht/wt.
So what Would be my function in cellforRow/numberOfRows/ and again retrieving these combos in didSelectRow.
2-Also, in the above Example the each row has 2 objects, What if there was another situation where i'd require 3 objects.
For example, Systolic Blood Pressure/Diastolic Blood Pressure/ Pulse pressure all entered by the user and retrieved in sorted timestamps,
IN this case each row will have 3 objects represented, and 3 rows will have 9 in total..
The number of objects represented in each row will be predefined before I call for entries, So i would know the number of objects each cell is going to have... just don't know how to go about it..
thanks for your help!
[EDIT:] I'll clear up one thing, that the Entries table - has its own Entryobject class
Each class has an-
-Value
-Timestamp
-CategoryID
The reason i don't want to have an Object defined for height/weight is because:
- height and weight are not returned in a single row.. it depends on the combination of category for example BodyMassIndex category will return a combo of 2 entries as explained above, So id have to compute here again, .. which defeats the purpose of the object itself.
Other reason being that i cannot define it, i wouldn't know if an entry is SBP, Ht or wt. Its what the CategoryObject would call, lets say for Ht entry and Wt entry, both have an CategoryID as 1. SBP, DP, PP will have a CategoryID as 2.
This way is for making the app more scalable for the future! though its taking me down!
Amm, got a solution using mAtH!! will this be super expensive on memory?
fieldCount is number of properties. ht and wt = 2!
limiterIndex=indexPath.row * fieldCount;
NSMutableArray *returnArray = [NSMutableArray new];
for(int i=limiterIndex; i<(limiterIndex+fieldCount); i++){
[returnArray addObject:[entriesArray objectAtIndex:i];
}
[cell setDataFromArray:returnArray];
[returnArray release];
Im not sure this will work, but it does seem to get the entries per cell from the all in one entries array!, at least on paper!
Seems like an expensive way to go about it?

You should make a custom object that holds every data you need in a single cell. Then put those in an array and use it as it's datasource.
In your case put the width and height data in some myObject. Then put those myObjects in an myObjectsArray and use that as its datasource.
Then in your cells extract a myObject and extract from those the height and width.
This you can use to fill the cell in cellForRowAtIndexPath:
This u can use for the dimensions of the cell in the heightForRowAtIndexpath:
Of course you can do this for other data as well. Just make a custom object which contains the data for you table.
So in short, I suggest making those custom objects and use those as the tableView's datasource.
You will figure it out.
Good luck.

I would create a model object that retrieves the master array of all entries.
This model object would also have methods that return the correct data based upon the index passed.
weightString = (NSString*)[self.dataModel getWeightAtIndex:indexPath.row];
I would then create the cells dynamically by adding text/field views to the cells as needed.
EDIT:
If you want a method that can vary in what it returns create one like :
weightString = (NSString*)[self.dataModel getDataAtIndex:indexPath.row forDataType:#"weight"];

Related

In BIRT is it possible to create a chart from summarized data columns?

Is it possible to create a line chart using summarized data from dataset?
My scenario is the following:
detail section: each one of the cells are one output field in the dataset
JAN FEB MAR
item1 R X R
item2 X A R
item3 R R R
footer section: here we count the occurrence of each value per month by using count aggregation elements and filter by value
TOTALS:
R 2 1 3
X 1 1 0
A 0 1 0
And what I need to do is to add a chart that shows something like this:
Needed Chart
And what I have is this:
report output
report design
In EXCEL this is really simple, but I cannot figure out how it can be done in BIRT.
I thought something like to create a new data set with 3 output fields for R, X, and A and each row will be one month, so I will have a transposed table and that way it will me much easier for graph it. But I cannot do it using the aggregation fields, and I cannot find out how to it with the output fields from the main dataset.
Any ideas? If you need the source rptdesign file I can provide it to you, but the logic in it could be hard to understand.
Any help is appreciated, and thanks in advance.
Have a great 2020.
First of all, a BIRT rule of thumb: if you need aggregations outside of a table, create them outside of a table. Do not try to access values in a table from the outside. It is possible, it may sometimes be the only solution, but it usually messes up your whole report, it is hard to debug, and even harder to maintain.
Aggregate
As your dataset looks quite simple and you already know how and what to aggregate, your first call should be computed columns in the dataset:
Here you aggregate in the language according to your datasource. If that is SQL, I guess a COUNT and GROUP BY statement will do the job.
Create all the columns you need for your graph here.
BTW: Computed columns are usually the silver bullet in BIRT. I use them for almost any pre-computation or custom field creation.
Visualize
You did not mention the library you are using for graphs, so I will assume you want to use the basic BIRT graphs. The basic charts with the months on the x-axis will do your job. I just want to add here that you have two options for multiple series:
You can either prepare your dataset so that you can feed the graph with a series per type (one line in your chart example) OR maybe easier: use optional y series grouping on your computed columns (as mentioned):
This way your graph will create the separate series for you. I hope this helps!
If you get stuck with the basic birt grpahs in general, you might want to think about finding a JavaScript-based graph library that does exactly what you need and implement that. Remember: you can put almost anything that is based on JavaScript into BIRT.
Final remark: For the sake of your report end users, please use a multi-bar chart. Line charts are not readable for overlapping values.
Thanks Kekzpanda for your help and time helping me in this question I had.
After struggling for a while I finally reach for a solution transposing the "table" of aggregations I had in the table footer, by using javascript arrays and an extra dataset and here are the steps I did in case someone else have the same problem:
For example, you need to transpose a table of 10 columns and 3 records
In report initialize method create an array with [10,3] dimension
// bi dimensional array indexes
var i=0;
var j=0;
// array definition and initialize it using 'for' iteration
var matriz = new Array(10);
for (i=0;i<10;i++){
matriz[i] = new Array(3);
}
// restart the array indexes in case you need to go through it in the future
i=0;
j=0;
Then you need to save the aggregation field value in one of the positions in the array. For that click on the aggregation field and go to the onCreate method and add the following code:
matriz[0][1]=this.getValue();
When finish all the aggregation fields, you will have an array with the transpose table. CHECKED!
Move the data in the array to the new dataset, select the fetch method and add something like this:
if(i >= array.length) return(false); // when you finish going through each item in the array.
row["A"]=matriz[i][0];
row["B"]=matriz[i][1];
row["C"]=matriz[i][2];
i++; // increment the first index by 1 to move to next row in the array
return (true);
Now you have your new data set with the transpose data.
Now work with this data set and graph the data, create the different series in the graph design for each column in the dataset.
Hope this help.
Bye.

Adding values to each row in Swift but not when row is dequeued & reused

I'm getting info from a GPS service giving an array of addresses, each one containing a duration of time in seconds. So from point A to Point B the time duration is 250 seconds and from Point B to C 100 seconds. It does not add the times together to make a complete route time, I have to do that on my own. In above example I would want to see 250 on the first row and 350 on the 2nd row etc. So I am calculating the values together to get the true total for each address by adding them from row to row right inside my table. I grab each address's value from the route's array based on my table index.path row. I populate that into a table and it works beautifuly as so:
let secondsToAdd = Int(self.thisRoute.ttaForSubleg(UInt(indexPath.row)).duration)
duration += secondsToAdd
However when table is scrolled up and down and cells are dequeued and re-queued values are getting added to again and again. I need to reset the duration somewhere to 0 as so:
duration = 0
but I'm stumped as to where!
Without another solution, my only way to do this I think would be to build and maintain an array separately outside the table instead of building it inside the table as I go along. If somebody has a better solution please post!

Tableau Future and Current References

Tough problem I am working on here.
I have a table of CustomerIDs and CallDates. I want to measure whether there is a 'repeat call' within a certain period of time (up to 30 days).
I plan on creating a parameter called RepeatTime which is a range from 0 - 30 days, so the user can slide a scale to see the number/percentage of total repeats.
In Excel, I have this working. I sort CustomerID in order and then sort CallDate from earliest to latest. I then have formulas like:
=IF(AND(CurrentCustomerID = FutureCustomerID, FutureCallDate - CurrentCallDate <= RepeatTime), 1,0)
CurrentCustomerID = the current row, and the FutureCustomerID = the following row (so it is saying if the customer ID is the same).
FutureCallDate = the following row and the CurrentCallDate = the current row. It is subtracting the future call time from the first call time to measure the time in between.
The goal is to be able to see, dynamically, how many customers called in for a specific reason within maybe 4 hours or 1 day or 5 days, etc. All of the way up until 30 days (this is our actual metric but it is good to see the calls which are repeats within a shorter time frame so we can investigate).
I had a similar problem, see here for detailed version Array calculation in Tableau, maxif routine
In your case, that is basically the same thing as mine, so you could apply that solution, but I find it easier to understand the one I'm about to give, I would do:
1) Create a calculated field called RepeatTime:
DATEDIFF('day',MAX(CallDates),LOOKUP(MAX(CallDates),-1))
This will calculated how many days have passed since the last call to the current. You can add a IFNULL not to get Null values for the first entry.
2) Drag CustomersID, CallDates and RepeatTime to the worksheet (can be on the marks tab, don't need to be on rows or column).
3) Configure the table calculation of RepeatTIme, Compute using Advanced..., partitioning CustomersID, Adressing CallDates
Also Sort by Field CallDates, Maximum, Ascending.
This will guarantee the table calculation works properly
4) Now you have a base that you can use for what you need. You can either export it to csv or mdb and connect to it.
The best approach, actually, is to have this RepeatTime field calculated outside Tableau, on your database, so it's already there when you connect to it. But this is a way to use Tableau to do the calculation for you.
Unfortunately there's no direct way to do this directly with your database.

How To customize different rows in UITableView

I want to create a page in iphone sdk which looks same as flight search result
problem is that each there are different number of stops some has 2 stops some has 1 etc. and not only leave flight detail but return flight detail can also be asked.
It must sorted on the basis of charges.
I am not getting from where I start
I make 3 custom cells
showing source n destination detail
the flight detail
to make separator between leave n return results
this is demo i have tried with fixed value! [1 row a SimpleTableIdentifier(background color not able to set) 2 and 3 row are 2 different CustemCell, there is separator custom cell too]
but I think i make it complex unnecessary
any tips and help will be apprecited thanks in advance.
Go like this make three customCell one for each of your three category
cell structure to show source and destination detail
cell structure to show flight detail
cell structure to make seperator
Now your UITableView will be a grouped tableView with numberOfSections = number to total flight you have to show
Each section will have three rows (if it has all three information available) else you can reduce the number of rows in any section by delegate method of UITableView named numberOfRowsInSection.
Try not to forget to give all different custom cells other dequeueReusableCellWithIdentifier's for re-usability.

Converting between unique NSIndexPath and unique NSUInteger (or int)

Is there a better way than what is proposed here to create a one-to-one mapping between an table view cell's NSIndexPath and a unique NSUInteger or int, in order to create a unique tag property value for a widget in the cell (a UIProgressView)?
The link adds methods through a UIKit category extension that converts between NSIndexPath and int, but they only work for less than a certain number of rows.
Granted, I may not run into that limit, but I'm wondering if there is a mapping that someone has come up with that can be guaranteed to work for any number of rows.
No, there really isn't a way that is guaranteed to work for any number of rows. If you have a table with 2 sections, each with 3 billion rows, then there's no way to map those 6 billion potential NSIndexPaths into the 4 billion 32-bit NSIntegers.
(if you were building a 64-bit app, the same thing is true, but the numbers would have to be another 4 billion times bigger in the example.)
They use a limit of 10,000 rows per section in the example you linked to; if you're seriously worried you might have more rows than that, you could use a bigger constant, i.e. you could use 1,000,000 as the maximum number of rows if you know you won't have more than 4,000 sections.
Note that a "real programmer" would presumably use 65536 as the constant, of course.
If I had a need to do this I would simply shift the section path to one half of a 32-bit int, and shift the row part to the other. Yes this means you can't have more than 65535 elements in a row (in breaking it out I assumed unsigned ints since row/section will never be negative) but I'll take an assumed limit far larger than I will ever need, over a magic constant any day.
Plus it's cheaper computationally.
Usually in this situation though I set up my table view controller as a delegate for each cell, and the cell can call back the controller with any changes along with some key value used to create the cell - after all when you are populating a cell you know how to reach into your data set to pull out values. Heck, you could even simply store the IndexPath into the cell and it can call back with that. The reason I would not use the IndexPath approach or the prior one involving flattening NSIndexPath into a tag is that if you ever start changing rows dynamically the values could become unaligned between the NSndexPath you created a cell with and the value for the current dataset. Much better to have some kind of key that will always get you back to the right data logically.