MapBox. A highlight effect by hover event on table. SetData takes 2s for updating source with 6000 features - mapbox-gl-js

I'm trying to implement a highlight effect by hover effect on the table's row. I've got the data table related to Mapbox's point features. I update the map point's styles by my rxjs state (every change in the state calls styles updating on my map). For small features count, it works well, but it takes 2 seconds for updating styles on the map with 6000 points. Directly setData execution takes 150-200 ms, but rendering takes 1-3 seconds. How can I improve the performance of the Mapbox for my task? As I wrote, I have 6000 points on the map, and when I hover the cursor over a row in the table I want to change the style for2 points. Change of style implemented by changing the feature's layer (might that be the matter?).
Thanks for any ideas.
the github issue.

setFeatureState is the most efficient way to update the styling of a small number of features on a map with many features.
It does have certain limitations: it only works on layers with feature IDs, and not all styling can be controlled through feature state (notably, layout properties such as icon-image cannot).
Documentation here: https://docs.mapbox.com/mapbox-gl-js/api/#map#setfeaturestate

I found more productive way to highlight any resource. I just use another data-source for selected / highlighted resources and one or few style layers. You only need to put selected resources to another data-source and draw them according selected style. That don't affective to common data sources, and don't need to recompute resources states, just draw selected resource above based resources.

Related

Is there an option to remove duplicate point labels within a distance in Mapbox Studio?

I'm using Mapbox Studio to label some point features (from a GeoJSON layer I uploaded) in a style, and there are some duplicate points located nearby each other:
Are there any options in Mapbox Studio to remove the duplicate labels automatically? For example, some other mapping programs have the option to remove duplicate labels within a specified distance (pixels or map units). Is this available in Mapbox Studio (or failing that, in Mapbox-GL-JS)?
Mapbox Studio does not provide a way to remove the duplicate labels automatically. You could work with a filter to manually filter out duplicates by writing a relatively complex expression, although this is not really the intended use case of expressions. You could also add a duplicate: true property to duplicated point features in your source data, but since this would require manipulating your source data, you might as well remove the duplicates from the source data instead of taking this approach.
That being said, you could consider clustering your data and styling the clusters so that a cluster looks the same as any individual point. This example shows how to create and style clusters using Mapbox GL JS. Here is a JSFiddle that heavily modifies this example to cluster closely-located points, and style the clusters in the same way that individual points are styled: https://jsfiddle.net/uo216fxz/ (you will need to add your own Mapbox access token in order to view the result). Text labels are added with the point count for each cluster containing more than one point, so that you can easily see that clusters and single points are identical aside from the labeling.
You will likely need to customize several properties (such as clusterRadius, clusterMaxZoom, etc) beyond what is provided in the linked JSFiddle, to be more specific to your source data.

Performance on changing colour of big geojson by using data-driven (comparing to using setPaintProperty)

I have been rendering a FeatureCollection of polygons into the Map (in one GeoJSONLayer). The size of each polygon is big (5mb, 10mb). With user interactions, the colours of polygons would be re-calculated & changed constantly. We are using data-driven method and keeping the data in properties of each feature. So GeoJSONLayer has to call .setData(geojson) everytime the data and colours changed (they are kept in properties).
I find above approach is lead to performance issue since the size of geojsons is big and calling .setData() is expensive.
I'm thinking of separating the geojson source and the data, style, colouring and calling direct function (setPaintProperty) whenever colours changed would be better than.
Someone told me that .setData and .setPaintProperty would do the same thing, both 2 will trigger re-rendering whole polygons.
Kindly need help to advice on this matter
Thanks a lot!
If I understand you correctly, you're asking which of these two is faster:
map.setData(mylayer, mygeojson)
map.setPaintProperty(mylayer, 'fill-color', ...mydatadrivenproperty)
I haven't tested, but I'd assume the second is faster, because the first one has to:
Parse the GeoJSON
Convert it to vector tiles
Repaint
whereas the second just has to parse the property repaint. Try them both out to see.
You may also consider a third way, which is to have a second layer which is a highlight, which you update by calling map.setFilter(mylayer, ...).

How to control what markers are displayed by mapbox-gl-js

I am loading a bunch of geojson points. I can see that I am loading about 40 points but which ones get displayed on my map seems random and somehow connected to the zoom level. Below you can see that only 2 points of ~40 are displayed.
What criteria does mapbox-gl-js use to decide what to display?
Is there a way to control what points are being displayed? (All of them? Some based on an attribute?)
This is likely occurring because you are using the default text-allow-overlap value of false. The text-allow-overlap documentation reads
If true, the text will be visible even if it collides with other previously drawn symbols.
Because your symbols overlap each other, some are hidden. You can disable this behavior by setting text-allow-overlap to true.
You might find marker clustering to be useful.

Is it possible to give different icons to a cluster group when it starts unclustering?

The red circles with numbers are clusters, but part of a bigger cluster when zoomed out.
Is it possible to change the marker/icon of the marker cluster in this present zoom depending on the markers that they have inside them? This without clicking them or anything, just change depending on the values of the markers that are hidden?
I have tried accessing the layer that is clustering all of them but I haven't been able to find the markers themselves, much less know how it would be possible to change the appearance of one without changing the other.
It looks like you already know how to customize your clusters appearance.
In the case your question refers only to the number of contained markers, you would just need to use a slightly modified version of the default iconCreateFunction to adjust the threshold values. When markers are removed/added from the MarkerClusterGroups and a cluster is de-/populated in consequence, its icon is re-drawn automatically. Customising the Clustered Markers
Now if you want this appearance to depend on some data from the contained markers, you would simply need to use cluster.getAllChildMarkers(); within your iconCreateFunction to get the array of markers contained within the cluster being styled. Then iterate through that array of markers, look for your data and create an icon accordingly.
Then, I understand that some data attached to your markers is changing, without any user action, and you want your clusters to update their appearance in consequence? In that case, please refer to this related question to upgrade your markercluster plugin with the new refreshClusters() method.
If your iconCreateFunction is properly designed, you do not have to worry about which clusters are changed. In fact, ALL clusters can be re-drawned, but if their markers data has not changed, they will get the same icon.

Interactive bar chart.user changes y axis value at runtime by dragging it

For example 3 columns are there with y axis value as 100,200,300 in barcharts.
User select one column alone and drag it to 500 value in y-axis.
How to achieve this?
Is it available in library like androidplot or aChartPlugin?
If not which plugin support this requirement.Our project is for Android tablets
Please provide me sample code for this requirement.Thanks in advance.
To my knowledge no library exists for Android that provides 'out of the box' capabilities to drag and reorganize data. Having said that, any library that provides you with a way to correlate touch events to data elements and also supports dynamic updates should be suitable.
If you have specific requirements about how the "drag" is implemented then you may end up having to roll your own library or customize an existing one to your needs. If not, here's a basic workflow you could implement with Androidplot that represents the drag operation as a cursor:
1 - Detect selections using an OnTouchListener. Here's an example of a bar plot that allows bar selection via touch. Gives a full example of converting screen coords to model elements etc. Create and add an instance of XValueMarker denoting the current position of the selection. (An XValueMarker is basically a customizable vertical line marking an x-val.
2 - Detect "drag" events using an OnTouchListener. Here's an example that detects zooming and scrolling. It's not the same thing exactly but the scrolling logic is close enough to give you the general idea.
3 - As the user drags, update the position of the XValueMarker by XValueMarker.setValue(Number).
4 - Once the "drag" ends, remove the XValueMarker and modify the underlying XYSeries to reflect the change using basic data structure manipulation(s).
And of course remember to always call plot.redraw() after each operation that is expected to alter the appearance of the plot in some way.