width and height doesnt change after rotating the screen in react native - reactjs

I am working on a RN app and I have an issue regarding the rotation and dimensions of the screen. I have a gallery application where I show three images in a row if the screen is vertical. I adjust it by dividing the width by the size of the image, I think this way of specifying the number of images in a row makes it consistent and changeable for different devices. However, after I rotate the screen, I was expecting to see more images in a row, but I didn't. I realized the width didn't change, so I saw three images again instead of 5 or 6. I am not sure if the way I am doing this is right or wrong. Any suggestions regarding this?? Also, how can I change the width and height dynamically, so that I can change the aligning of my gallery after rotation?
here is a part of my code
...var {height, width} = Dimensions.get('window');
var imageSize = 120;
// number : number of images in a row
var number = Math.round(width/imageSize);
console.log(number);
var CameraRollView = React.createClass({
propTypes: propTypes,
getDefaultProps: function(): Object {
return {
groupTypes: 'SavedPhotos',
batchSize: 5,
imagesPerRow: number,
assetType: 'Photos',
renderImage: function(asset) {
//var imageSize = 120;
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
return (
<TouchableHighlight onPress={
()=>{
/**fire gallery action selectImage*/
this.selectImage(asset.node.image.uri, this.images);
}
} key={asset.node.image.uri}>
<Image
source={asset.node.image}
style={imageStyle}
/>
</TouchableHighlight>
);
},
};
},
...
here what important is -imagesPerRow- I want it to be dynamic, as I rotate the device.

I would recommend against using the Dimensions module if you need to respond to screen size changes.
The View component provides an onLayout property that is called each time that View's layout has to be recalculated (e.g. on device rotation). I don't know anything about the architecture of your app, so I will just say the easiest way to use it in my opinion is to set it to a function on the root View in your app that writes the new parameters to state (or to your flux/redux stores if you use that).
You can then pass that information through your app and use it as you see fit.

Related

How to set Bar width In Rgraph?

I am not able to set bars width if there is only 1 or 2 bars in chart.
I am using Rgraph in my angular 7 app. I am unable to set marginInner property value based on the number of bars.
Is there any property to set the barwidth directly.
There's no property to set the width directly, but what you can do is put the logic for calculating the marginInner in the draw event or an exec() function. Here's an exec function example:
new RGraph.Bar({
id: 'cvs',
data: [8,4,6,3,5,1,5],
options: {
}
}).draw().exec(function (obj)
{
// Calculate marginInner here,set it and call RGraph.redraw();
});
This means that it runs only once after the chart has been drawn so you can then access the data (with obj.data) and then calculate how big the margin should be.

Is there a way to restrict the scroll window of react-calendar-timeline to only visible time start and end?

I am using react-calendar-timeline and there I am using controlled scrolling feature very similar to this example. Now as you can see only current date is being displayed but user can scroll the canvas to previous and next date. That means canvas is taking 3x width of the dateRange.
I just need the current date to be displayed in canvas only.
Thank you in advance.
I have also dug a lot over the docs and internet to solve this problem.
Finally, I got it. I am sharing my solution with those who are in the same situation.
Create defaultTimeRange and set to min and max zoom props to disable the zoom.
Then write a handler function for onTimeChange and take the third callback funciton to disable the scroll.
// Set the visible start and date somewhere in the beginning like this using useEffect
setVisibleTimeStart(currentDate.startOf("day").valueOf());
setVisibleTimeEnd(currentDate.endOf("day").valueOf());
...
const defaultTimeRange = visibleTimeEnd - visibleTimeStart;
<Timeline
...
minZoom={defaultTimeRange} <--- To disable Zoom
maxZoom={defaultTimeRange} <--- To disable Zoom
onTimeChange={(_start, _end, updateScrollCanvas) => {
updateScrollCanvas( <--- To disable Scroll
moment(visibleTimeStart).valueOf(),
moment(visibleTimeEnd).valueOf()
);
}}
>
Then you have to override one css class like this
.react-calendar-timeline .rct-scroll{
overflow-x: hidden !important;
}
I have created 3 variables
const defaultTimeStart = moment().add(0, 'hour');
const defaultTimeEnd = moment().add(6, 'hour');
const defaultVisableTimeEnd = moment().add(24, 'hour');
// create calendar view of one day
const defaultTimeRange =defaultTimeStart - defaultVisableTimeEnd;
<Timeline
...
minZoom={defaultTimeRange}
maxZoom={defaultTimeRange}
//it will not allow to scroll more than [enter image description here][1]a day
onTimeChange={(_start, _end, updateScrollCanvas) => {
if (_start > defaultTimeStart && _end < defaultVisableTimeEnd)
updateScrollCanvas(_start, _end);
}}
/>

Azure maps layers are getting on top of each other

I'm using azure map.
What's happening is that I have 2 layers. A layer that have Circles and a layer with polygons.
I have a functionality in which a popup appear when I click on a specific circle.
The issue occur when I add the polygon layer after the circle layer.
It's like the polygon layer is being drawn on top of the circle layer. In which it prevent the popup from appearing when clicking on the circle.
Here's how I'm adding the polygon layer:
showFetchedResultOnMap(facilities) {
const self = this;
if (facilities && facilities.length > 0) {
self.cleanRestrictionLayer();
//Create a data source and add it to the map.
self.datasource = new atlas.source.DataSource();
self.map.sources.add(self.datasource);
//Add a data set to the data source.
self.CleanMap();
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
self.map.sources.add(datasource);
self.map.imageSprite.add(self.chosenCategory, 'assets/svg/' + self.chosenCategory + '.svg')
.then(function () {
facilities.forEach(cat => {
datasource.add(new atlas.data.Feature(new atlas.data.Point([cat.longitude, cat.latitude])));
});
//Add a layer for rendering point data as symbols.
self.map.layers.add(new atlas.layer.SymbolLayer(datasource, self.chosenCategory, {
iconOptions: {
//Pass in the id of the custom icon that was loaded into the map resources.
image: self.chosenCategory,
//Optionally scale the size of the icon.
size: 0.1
}
}));
});
}
}
Anyone have an Idea about how I can fix this??
I'm not seeing a polygon layer in the code you provided. That said, when you add layers to the map, the order in which you add them is the z-index by default. Last one added goes on top. That said, when adding the layer using the map.layers.add function, there is a second parameter you can add in which can be another layer or layer id. When this is specified the layer you are adding will be inserted below that second specified layer. Here is the doc on this: https://learn.microsoft.com/en-us/javascript/api/azure-maps-control/atlas.layermanager?view=azure-maps-typescript-latest#add-layer---layer----string---layer-
Here is a short example:
map.layers.add(new atlas.layers.BubbleLayer(datasource, 'myBubbles'));
map.layers.add(new atlas.layers.PolygonLayer(datasource, 'myPolygons'), 'myBubbles');

Rare effect when toggling BaseLayer in leaflet with react-leaflet

My application shows a map with react-leaflet and uses LayersControl to switch between an OSM TileLayer and HERE TileLayer. The code is as follows:
<LayersControl position="topright">
<LayersControl.BaseLayer
name={this.props.intl.formatMessage({id:'map.normal_map'})}
checked={true}
>
{ tileLayerOSM }
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name={this.props.intl.formatMessage({id:'map.terrain_map'})}>
{ tileLayerHERE }
</LayersControl.BaseLayer>
</LayersControl>
The problema I see is the following: when moving the OSM map, some 'squares' are downloaded from HERE while they are not ready with OSM. See the network trace:
I would like to avoid this behavior, since it is a bit annoying for the user, who see changes in the visualization for a short period of time.
I don't have experience using Leaflet with React, but these is clearly not the desired behaviour.
In Leaflet that (retrive the both base layers at the same time) happens when you add both to the map. Something like:
const accessToken = 'foo';
let osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
const mapbox = 'https://api.mapbox.com/styles/v1/mapbox/basic-9/tiles/256/{z}/{x}/{y}?access_token={accessToken}';
const map = L.map('map').setView([42.2, -8.8], 12);
map.addLayer(osm);
map.addLayer(mapbox); // only one should be added to the map
or directly when instantiating the map:
let map = L.map('map', {
center: [42.2, -8.8],
zoom: 12,
layers: [osm, mapbox] // only one should be added to the map
});
With this kind of baselayers you only must add one to the map and use the layer control to switch between one or the other. When only one is added only the tiles for one of the maps are requested, saving bandwith.
As a "shot in the dark" I will try to make the checked value explicit for all layers. First both as a harcoded false, nothing should be shown in the map. Then one with checked=true harcoded and the other with false, and so on. Probably the trouble is how those attributes are managed.

OpenLayers: Zoomable WMS overlay?

I have a problem with WMS overlays in OpenLayers. Basically I just want to add data from a WMS server as an overlay and not as a base layer. This appears to be a very simple problem but I am unable to find a solution. If I set singleTile to true, the overlays appears over the whole map but you cannot zoom in. If it is set to false, only one tile is displayed at every zoom level. If I set it as a base layer, it works just fine but I really want the overlay solution so I can make it transparent and see the map behind it.
Demonstration of the problem, with a different dataset but the issue is the same:
http://jsfiddle.net/adbnC/2/
I think it might be related to some coordinate system issues but I am no expert so any help is appreciated.
Thanks a lot!
Here is the relevant section of the code that does not work as expected:
var pop_layer = new OpenLayers.Layer.WMS("Population Density in 2000",
"http://sedac.ciesin.columbia.edu/geoserver/ows", {
layers: 'gpw-v3:gpw-v3-population-density_2000',
transparent: true
}, {
opacity: 0.5,
isBaseLayer: false,
// Setting single tile to true will kind of work but than one
// cannot zoom in any more.
singleTile: false
}
);
I can't quite get what exactly is wrong here, but I think it has something to do with messed up reference systems. Here is a workaround:
Modified Jsfiddle.net
I changed the map projection to spherical mercator and now it seems to work fine for me:
var mapOptions = {
div: "map",
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m"
};
map = new OpenLayers.Map('map', mapOptions);
var osm = new OpenLayers.Layer.OSM();
map.addLayer(osm);
var pop_layer = new OpenLayers.Layer.WMS("Population Density in 2000", "http://sedac.ciesin.columbia.edu/geoserver/ows", {
layers: 'gpw-v3:gpw-v3-population-density_2000',
transparent: true
}, {
opacity: 0.5,
isBaseLayer: false
});
map.addLayer(osm);
map.addLayer(pop_layer);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.setCenter(new OpenLayers.LonLat(0, 0), 2);​
Let me know if that helped!

Resources