Refreshing a source in order to update the visualized data - mapbox-gl-js

I am implementing a time based mvt service with data from different time periods and the possibility to navigate through that data. Based on the year the tile server sends an mvt of that specific timeframe and a coherent styling gives the visualization. I would need to be able to update the data (invalidate and reload) in the viewport without resetting the style (and as such avoiding the flicker effect) considering the changing date and not only the changing coordinates.
https://map.openhistorymap.org/867.906/4.320382571983785/49.43846097119561/6.200660841932859

There seems to be a problem with the documentation, but the feature you want is apparently available in Mapbox-GL-JS within the last couple of months, according to this commit.
You should be able to do something like:
map.getSource('myvectortiles').setTiles(..)
or
map.getSource('myvectortiles').setSourceProperty(..)
to trigger an update. You may need to look at the source code for more details.

Related

ag-grid with virtual scrolling without lazy load

I have a requirement where we need to show around 24k records which has 84 cols in one go, as user wants filtering on entire set of data.
So can we have virtual scrolling mechanism with ag-grid without lazy loading?? If so could you please here. Any example are most welcome for reference.
Having tried this sort of thing with a similar number of rows and columns, I've found that it's just about impossible to get reasonable performance, especially if you are using things like "framework" renderers. And if you enable grouping, you're going to have a bad time.
What my team has done to enable filtering and sorting across an entire large dataset includes:
We used the client-side row model - the grid's simplest mode
We only load a "page" of data at a time. This involves trial and error with a reasonable sample of data and the actual features that you are using to arrive at the maximum page size that still allows the grid to perform well with respect to scrolling / rendering.
We implemented our own paging. This includes display of a paging control, and fetching the next/previous page from the server. This obviously requires server-side support. From an ag-grid point of view, it is only ever managing one page of data. Each page gets completely replaced with the next page via round-trip to the server.
We implemented sorting and filtering on the server side. When the user sorts or filters, we catch the event, and send the sort/filter parameters to the server, and get back a new page. When this happens, we revert to page 0 (or page 1 in user parlance).
This fits in nicely with support for non-grid filters that we have elsewhere in the page (in our case, a toolbar above the grid).
We only enable grouping when there is a single page of data, and encourage our users to filter their data to get down to one page of data so that they can group it. Depending on the data, page size might be as high as 1,000 rows. Again, you have to arrive at page size on a case-by-case basis.
So, in short, when we have the need to support filtering/sorting over a large dataset, we do all of the performance-intensive bits on the server side.
I'm sure that others will argue that ag-grid has a lot of advanced features that I'm suggesting that you not use. And they would be correct, for small-to-medium sized datasets, but when it comes to handling large datasets, I've found that ag-grid just can't handle it with reasonable performance.

Bing maps v7 to v8 upgrade causes increase in billed requests

I recently completed upgrading bing maps from v7 to v8 for our dealerlocator. Since then we have observed increase in the no. of billed requests.
I did not change the way map API were being called during the upgrade process. Still, it shows an increase in no. of billed requests.
Can someone help me understand any specific reason for the same? Also how do I calculate no. of billed requests using JS in my code during development? Ideally I want to count the no. of requests for every load of this particular module. Please help :(
If you are simply loading a map a single billable transaction will be generated each time the map is loaded. If you load the map on page load then the number of page views would normally be around the same number as billable transactions. If you use the search or direction modules they will generate non-billable transactions as they are part of the map session.
If you use the auto suggest module, without a map, this will generate a billable transaction the first time a suggestion is selected.
We have done a lot of testing and have most V7 apps migrated to V8. We haven't seen any increases in usage in transactions in general. Any increases that were observed were due to the following:
App developers were comparing current month to previous month. This isn't accurate as web traffic generally fluctuates month to month. It is best to look at the last two years worth of reports to see if the month is question is typically a higher month and to also look at the average month on month growth as web traffic usually increases over time.
The new application attracted more users to use it. Sometimes additional marketing may have also been involved.
There was an issue with the code that the developer migrated which generated more transactions. For example, calling the map load function twice, once using the page onload like in V7 and once using the callback parameter in V8. This would result in twice as many map transactions being generated, but appear as only a single map on the page.
The previous application didn't use a key and either used v6 of Bing Maps or had CSS which hide the error message that appears in V7. We have seen this in a number of applications. Basically, the old application should have been generating more transactions than it was.
A list of the different ways transactions are generated is documented here: https://msdn.microsoft.com/en-us/library/ff859477.aspx

Instagram API: Get the oldest images first based on tagname

I recently developed an app using the Instagram API, But I faced some problems with it. (I got struck)
This app is not calling the api and getting images in the real-time. Instead, it calls the api once a week and store images in the database based on a specific hashtag. I see that their api is designed in a way to call it in real time and pull images, because it has this "recent" in its url, and it only provides 20 results. So every time a user reaches the end, it will load the next 20, until u reach the end.
However, in my case, When I pull the images every week, at one point, I will reach to the oldest image, and from that point I will be stopped, because Im going from Newest to the oldest. So I want to get data as from oldest to newest.( Actually I want to get the opposite of what's offered by instagram.) They have not provided any option to sort them in their docs.
Im thinking of a solution for this, but I can't wrap my head around it. So I will be much thankful if you guys can direct me in the right path.
I searched Google, viewed old questions in SO, but I didn't find the answer.
Edit : Im planning to fetch data starting from the Oldest one like this. (Since I know the min_tag_id, because I ran this once completely).
https://api.instagram.com/v1/tags/my_tag/media/recent?&client_id=xxxxxxxxxxxxxxx&min_tag_id=1408983759354183
where min_tag_id is of the oldest image. So everytime I will be calling to the min_tag_id. Is it a good solution?
Yes, using the min_tag_id and max_tag_id is the solution.
Have a look at this answer: Instagram Search for a tag within particular date range

How to programmatically create a new version of a CQ5 page?

Is it possible to programmatically create a new version of a CQ5 page that has a start time some time in the future?
As an example, let's say we have a page that displays tax rates. We have a component that allows the author to upload a new rates table (in the form of a css file) and it creates the rates page content. We would like to allow the author to upload rates that will be effective the first of next month.
I know the jcr supports multiple versions of nodes, but its unclear how (or whether) this relates to cq5 page versioning. And, further, whether a new version can be activated in the future.
Given the requirements as you've described them, I would probably accomplish the task in a slightly different way...
Instead of storing my rates table information directly within the page's jcr:content node (or a sub node their of) I'd probably abstract it out to somewhere else in the repository. You could then, if you so desired, create some sort of an admin interface to allow content authors to upload their csv file of new rates, and ingest that into the repository as needed. Alternatively, assuming that data comes from some sort of a database, you could probably just write a job to automatically injest it on some sort of a scheduled basis by using a JDBC connection from CQ. Once the data is in the repository, you could then write the display component to read the data from the repository, instead of it being directly inside the page.
This approach has the advantage of making that data re-useable within CQ to be shown on multiple pages, multiple sites, even many different display formats if need be. In addition, you can design your jcr structure to support whatever requirement you have around updates to the data, including daily, monthly, weekly, yearly etc., obviously this will depend on the specific requirements.
The one downside to this is that since there is a separation b/w the data and the page(s) where it is displayed, you may need to find a way to ensure the cache is properly cleared whenever the data does change.
Update (based on your comment):
The problem I foresee with versioning the page, and granted I've not tried this so maybe it will work, is that there can only ever be one active version at a time. Therefore, once the next months data is uploaded, you need to maintain the old data (active) and the new data (not yet active) at the same time. What happens if you require a separate content change during that window...from a business process perspective that just seems messy to me.
Back to cache clear issues, If you know the affected pages, especially if they are all in one subtree, you could write a custom workflow process that uses the replicator service to clear the cache for the affected pages, then set up a launcher to run the wf on node change for the data.
The other option, and this one is less defined in my head, so some experimentation required, would be to use CQs built in activate later and de-activate later functionality.
Maybe create a specific template for the rates data, with the implicit requirement that only one page using that template is ever active at one time. Your display components could use a query to find the currently active rates data.
I have not personally tried this, but...
I assume that you can use the PageManager service's createRevision method, and then if that returns without throwing an exception, you may call page.getContentResource.adaptTo(Node.class), and from there take the node that is returned and edit the JCR properties for your tax rates component.
See PageManager
You could write a workflow that includes a publish step that is triggered by the arrival of a calendar date. The version of the page with the new tax rates remains in the workflow pipeline in draft form and is only published/activated when the date arrives. (So you'd need some sort of process that wakes up once a day to check the calendar.)
Each time a page is modified cq creates a version of the page.
This modified page's modification time is set in jcr:lastModified property of the page.
Manipulation of this property can be done to save future date and activate page on that date though its not preferred way.
You can store the future date as a property in the page.
Later as suggested by #David you can create a workflow or a scheduled job which activates pages with a future date.

Beginner database troubles

I have an iOS app that presents content in a tableView. I've added a 'like/dislike' feature that interacts with my database (I use Parse.com). Every time someone likes/dislikes a piece of content, the specifics are sent to the Parse database. For each piece of content, I'd like to calculate and display the percentage of 'likes' over 'likes' + 'dislikes'. This is pretty simple math, but I can't wrap my head around the best way of designing my database table and the most efficient way to calculate the 'liked' percentage for each piece of content before the tableView physically appears.
As it is, I already have a loop in my tableView's viewDidLoad which compares the content from another database table to the 'like/dislike' table to restore the 'like/dislike' button state of the user (if they already liked/disliked a piece of content).
At first, I thought of creating an array in the initial viewDidLoadloop. However, using the whereKey: equalTo: type of query for each piece content to simply find the amount of likes/dislikes takes forever. As predicted, it is very slow in cellForRowAtIndexPath as well.
Worst case, I can make these calculations server-side and just pull the 'liked' percentage. However, I'd like to implement this in the app somehow. I'm a complete beginner, so I may be going about this all wrong.
Here is the basis of my database table:
Edit: I've managed to build a server-side program that calculates the percentage of users that 'like' pieces of content. My app pulls this percentage from the database at runtime. To make the percentage change more responsive when the user 'likes' something, I locally calculate an updated percentage. The problem here is when the user exits the app and reopens, the data reloads. If the server-side program had not run recently, the app will display an old 'liked' percentage (the most up to date % would not be calculated yet). The two solutions I see to fix this are:
Run the server-side program every 1-3 min
Post more data to the database when someone likes content (this would involve additional database queries for every single 'like').
I think both of these options are way too expensive for what I'm trying to accomplish.
I'd suggest leaving the calculations to the server side, and responding with the information to utilize in the app. This will save you from processing and parsing the incoming results.
You have greater processing power on a Server than on a device.