iPhone iOS how to deal with time gaps in Core Data when presenting a graph? - iphone

I'm running into a problem of how to display sequences of core data entities on a single graph, if there are time gaps between sequences.
I got a fixed-length bar graph (backed by UITableView) with each bar represented by a core data entity, all entities are timestamped and follow each other, so sorting such data results in a graph like below. The good thing about such graph is that NSFetchedResultsController can be used to dynamically update the table view in response to new events being added. The result is that it appears to the user that new bars are added on the left as time goes by.
My problem is that I want to expand this graph and make it 24 hour long and scrollable side to side. In this case, there will be episodes where no data will be present in the app. The end result is that if I rely on NSFetchedResultsController when there are gaps in data, and I want to display blank cells for missing data.
I'm interested in how you would approach the problem.
I see two potential solutions:
1) Drop the approach of using NSFetchedResultsController, and instead manually calculate the number of bars in a UITableView. Each bar is defined by a start date and an end date. Then I can use NSFetchRequest with predicate to query each bar's data. If there's an event with a timestamp that falls within the bar's date range, then a bar is shown, otherwise a blank is shown.
The problem with approach #1 is that it is slow, and while it does allow scrolling through the entire data set, it is slow and laggy, as each fetch request is executed for each new bar. Additionally, I need to manually refresh the table in response to new data being added, which is difficult to implement properly.
2) Maybe I can pre-populate the data set with blank events, and then "fill them in" as data becomes available. This would allow me to keep the table view with fetched results controller, resulting in smoother scrolling, but at the price of significantly increasing the persistent storage used by the app (as blank entities will be created between app use).
I'm wandering if there's an additional approach that I'm not thinking of. How would you create a side scrollable bar graph that would allow for "gaps" in the app's persistent data storage?
Thank you for your input!

Your question really doesn't have (or shouldn't have) anything to do with Core Data or NSFetchedResultsController. How your graph view draws the data it's given is entirely up to the graph view. There's no reason that you couldn't write a graph view that uses NSFetchedResultsController and deals appropriately with gaps in the data, but UITableView was never intended to deal with missing/empty cells.
The problem is not that you're using either Core Data or NSFetchedResultsController. The problem is that you're abusing UITableView.
Drawing a bar graph is pretty easy -- it's just a series of rectangles drawn at appropriate locations. You can give your view a fetched results controller and have it look at the fetchedObjects property to get the current list of objects. It can then render as many of those objects as it likes, and it can use the start and end date of each object to locate the drawing on the graph. Put your graph in a UIScrollView so that you don't have to worry about scrolling. If the graph can get large, add tiling so that you're only drawing the parts that the user is looking at, just like UITableView does.
It looks like you're currently drawing some content above your table view, too. If you create your own graph view, you might consider drawing that additional content (the red line, the red and green bubbles, the high REM probability thing) at the same time. Doing that will make it easy to ensure that all that content is located correctly on the graph (which is probably a bit of a pain with your current scheme).

Related

ag-grid: Does the infinite scroll feature support scrolling up rather than down?

We currently use react-base-table as our solution for an infinitely scrolling table component, but it runs into performance problems with a large number of columns because it does not virtualize horizontally. My understanding is that ag-grid does, so we are looking at it for primarily performance reasons.
Our app defaults to displaying data (log events) from bottom to top. The user is initially placed at the bottom of a potentially large virtual dataset (could be millions of events), and they scroll up to load and view more events (200 at a time).
After reading through ag-grid docs and searching here, I don't see anything about support for an upward direction for infinite scroll. Am I missing anything?
I've tried implementing it with the default row model, but am running into errors (eg "cannot draw while in the middle of drawing rows"). The 'onViewportChanged' event I'm using to trigger a fetch is called several times when rendering, and messes up our data model. Infinite scroll seems like the correct approach.
Yes, it is possible.
You will need to set serverSideInitialRowCount={1000} so the grid could adjust scroll size. And then in the onGridReady event call api.ensureIndexVisible(999).
The grid will request only the last data block, and will request other blocks as you scroll up.

Show annotation on MKMapView based on user location

I've problem with Objective C at the moment with developing something special.
So - after the MKMapView is initialized and the users position is shown, I would like to implement a method to show annotations which are next to users position. I've stored all necessary points in an SQLite database in a special table. I've two fields - namely lonand lat- I think it's clear what is meant by that.
Has anybody an idea how to show JUST those annotations which are visible at the screen to be as performant as possible. After the user scrolls the map - it should call the method again to look up in database wether there are also other points which need to be shown...
Thank you very much in advance for your help,
kind regards,
Dominik
You will need to do a few things.
1) Get the center of your map - use the centerCoordinate property of your MKMapView
2) Ask your database for all items within a certain distance from the center of the map.
3) Display them
It's (2) that's the tricky one - you need a method that will return all items near to the lat lng you have.
This link has a handy implementation of how to do that :)
Hope that helps.
A couple of points:
If you're using iOS4, the mapview behaviour has changed so that it automatically saves memory by only creating the annotations which are in the visible view.
Secondly, in the same way that you can create a tableview with thousands of cells and still have it scroll smoothly, the annotations offscreen don't affect the performance that much. You should be keeping your annotations very small so they don't consume much memory. The annotation views are the ones that take up the memory.
Your problem is going to come when the user zooms out and there are too many annotation views visible at the same time. When you're zoomed in, you don't need to worry too much about off-screen annotations.

Possible to reuse UILabels on a scrollview?

I'm trying to implement a view that shows a grid of information without using a UITableView, however, since I'm displaying about 36 different statistics, with its label I will have to initialize and use 72 UILabels. Does having so many UILabels mean that my iPhone app's performance will be significantly negatively affected? Is there a way to reuse some of the UILabels to decrease the number of UILabels that must be loaded at one time, or should I just resort to drawing everything on a surface instead?
First of all you should test the interface your thinking of and see if it takes a performance hit. Having a lot of labels all loaded at once will increase your memory footprint but depending on what else is going on in the app, it might not matter.
Secondly, you can't easily reuse the labels but it is possible. However, you would have to constantly monitor the displayed area of the scrollview and move the labels frames around as the view scrolled. I doubt you could do that efficiently. It would take a lot of coding in any case.
Thirdly, any grid like layout can be easily displayed in a table without making it look like a table. For example, the photopicker layout is a table but it looks like a bunch of icons on a white background. Another app I saw used a table to display paragraphs of text but it looked like an ordinary scrolling textview. Every row in a table can be customized to display exactly what you want. In principle, you could use a different cell for every row and they could all be unique in their height and contents.
The advantage of the table is the the table manages what is and is not on screen for you. It does reuse cells and their contents which makes them more efficient. The table also makes it easier to manage a lot of data.

How can I show relationships between views in Visio database diagrams?

I'm using a set of views for the data access layer of our primary web application, and need to document these views. Logically the views mirror the underlying tables, meaning they have similar relationships to the tables. (It's a bit more complex, since the views are pulling data from 3 databases...)
So I opened up Visio and reverse engineered the views in question into the diagram, but the problem now is that Visio won't let me add relationships to views.
Is there any way around that limitation so that I can model these views as if they were actually tables?
Or is there an easy way to "convert" each view to a table? (I could do it manually, but that's a lot of boring typing for all the properties...)
Have you succeeded in this? I need to document data layer based on related views, but in addition to the problem related to relations there is another one: when model is refreshed the tables in the drawings update nicely but all chenged views disappear from the drawing. The model is updated, i.e. if I drag the views back on canvas the content is updated. But still I don't want to rebuild the whole picture every time a small update is done on the DB...

iPhone 3.0 MapKit - Multiple Annotations in the Same Location

Background: I have created an application that allows users to submit an entry to an online database, and view other entries from that database. These entries contain geocodes for latitude and longitude which are used for positioning the annotations on the MapKit. Users can submit the location using either their current location or an address, which is then geocoded.
Question: What is the proper or suggested method of handling annotations that fall on the exact same coordinates?
I was thinking of checking if there are any duplicate geocodes in the XML file pulled from the database and creating a single annotation with a custom annotationView that displays all of the separate ones. In addition, I was thinking of checking for duplicates and displaying "Multiple Entries..." and having the detail view display a table view with all of the entries.
Am I on the right track?
I think you are on the right track, you should check for duplicate geocodes and merge them into one. Displaying many annotations with the same location could be confusing because the pins will stack on top of each other and will be hard to diffrentiate and to click one by one.
Are you talking exact same geocode or kinda sorta close? Because if it's exact, then you're on the right track, but if it's +/- delta-T then you may have to come up with a different way of handling them since when zoomed-in all the way each location could be distinct. An easy way to hanle it is to drop or round-off decimal points in the lat/long value based on the zoom factor before checking for coordinate equality.
Other than that it sounds like you're on the right track. You will probably want to do both the custom annotation view (but that could work for only a few items) with the option to move on to a separate table view if there are more items to show.
One other thing I'd add is you could make it so your placemarker shows the number of items that co-reside in that location. You can do this by sticking a text label on top of your custom placemarker view and putting the number in it or by having pre-rendered icons with say, 1-9 and "..." (for more than that) in the heads of the markers. That way the user can quickly see there's more items to look for.