I'need to show user feed with items where every item contain a chart.
Now I use react-native-svg-charts:
<LineChart
style={{ height: 150, position: 'relative', left: -20 }}
data={data}
curve={shape.curveNatural}
svg={{ stroke: chartColor1, strokeWidth: 5 }}
contentInset={{ top: 20, bottom: 20 }}
showGrid={false}
numberOfTicks={0}
key={props.id}
>
But when I load more then 50 items performance of the app fall down to 10-15 fps.
I think it because of many SVG's on page. Which solution do you think should I use to avoid this?
I answered a similar question recently here: Real-time data update chart in React Native and will suggest the same here.
I've struggled with performance when plotting in React Native with all of the SVG-based libraries I've tried. I recently decided to try using a couple canvas-based plotting libraries within a WebView and had very good results. I ended up making a simple package: https://www.npmjs.com/package/#dpwiese/react-native-canvas-charts.
Should you not want to use this package and instead do it yourself, it's quite straightforward. While the package source code is probably the best resource I'll summarize the steps below:
Create an HTML file and import it into your component:
const htmlTemplate = require("./index.html");
where the HTML contains the JavaScript for the charting library of choice. The linked package above currently supports Chart.js v3 and uPlot. In the steps below I'll show a Chart.js configuration.
Create a ref, for example let webref.
Create a WebView and onLoadEnd you can inject some JavaScript into the WebView that will configure and create your chart
<WebView
originWhitelist={["*"]}
ref={r => (webref = r)}
source={htmlTemplate}
onLoadEnd={() => { addChart(config) }}
/>
where addChart looks something like:
const addChart = config => {
webref.injectJavaScript(`const el = document.createElement("canvas");
document.body.appendChild(el);
window.canvasLine = new Chart(el.getContext('2d'), ${JSON.stringify(config)});`);
};
and config is a valid Chart.js configuration.
To update the chart data simply inject some JavaScript to update the data. In the case of Chart.js here, that'd look like:
const setData = dataSets => {
if (dataSets) {
dataSets.forEach((_, i) => {
webref.injectJavaScript(`window.canvasLine.config.data.datasets[${i}].data = ${JSON.stringify(dataSets[i])};
window.canvasLine.update();`);
});
}
};
where dataSets are valid Chart.js data sets.
That's it! I've only played around with these two plotting libraries via the https://www.npmjs.com/package/#dpwiese/react-native-canvas-charts package, but so far performance has been really good, even with the JSON stringification of all the passed chart data. I haven't quantified it thoroughly, but both libraries are orders of magnitude more performant than any of the SVG-based ones I've tried.
Related
Before you link me to another question similar to this one, such as this or that. I will say that I have done exactly what the answers said, but my gif won't animate as it should (It is displayed though).
Here is what I've done in a function, which is displayed through the main App function Stack.Screen within a NavigationContainer and Stack.Navigator. (I'm using React Navigation to move across screens, the context here is that a button is pressed and it displays the contents of the DetailsScreen function)
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 2, alignItems: 'center', justifyContent: 'center' }}>
<Image source={require('./src/gif/moving.gif')} />
<Text>Here is a gif</Text>
</View>
);
}
This displays the first still image of my gif, but doesn't animate it.
I also already went ahead and placed the implementations in the build.gradle dependencies, but it didn't do anything for me. I have a feeling the problem lies there.
implementation 'com.facebook.fresco:fresco:1.+'
// For animated GIF support
implementation 'com.facebook.fresco:animated-gif:1.+'
// For WebP support, including animated WebP
implementation 'com.facebook.fresco:animated-webp:1.+'
implementation 'com.facebook.fresco:webpsupport:1.+'
(I already checked fresco's new implementation version 2, but it still didn't help. I also tried changing from a specific version, still doesn't work)
I am using React Native version 0.67. (I tried starting it again while downgrading react-native to 0.66 and it still doesn't work.)
Also, not sure if this has to do with anything in this screenshot here, this is what I had by default and gave me this error message as soon as I opened the file, but the program launches just fine even with that on
Doing it normally in the main App() function starting first displays the gif, but still remains as a still image.
What should I do? I mean... what else can I do?
Edit:
I found the solution to the problem... it was a simple case of just cold booting the emulator I was using from android studio.
However, Tadej's answer is valid, as the view style aligning messes up the gif a bit. If you are having a similar problem and the answer doesn't help, try cold booting your emulator, or even reinstall a newer one... or alternatively, use a real android phone to test these sorts of things.
Anyway, thanks a lot for the help Tadej ! I hope this question has helped others in my situation.
Tadej Slemenšek
This worked for me. Setting height and width on Image prop did not show the gif. So I flexed it and added maxWidth and maxHeight.
const imageUrl = 'https://media.giphy.com/media/xT0xeCCINrlk96yc0w/giphy.gif';
const App = () => {
const { width } = useWindowDimensions();
return (
<View style={{flex: 1}}>
<Image style={{flex: 1, maxWidth: width, maxHeight: width}} source={{uri: imageUrl}}/>
</View>
);
};
I have a project that simply displays a website. My code is:
function pencere() {
var self = Ti.UI.createView({ width:"100%", height:"100%" });
var webPencere = Ti.UI.createWebView({ left:1, right:1, top:1, bottom:1, url:"http://www.radyobasaksehir.com" });
self.add(webPencere);
return self;
}
My friend told me that the Android browser doesn't support the new CSS and HTML codes. I don't know the exact meaning of these but I think I need to revise my code but I couldn't figure that out.
The problem is related to chromium WebView being used Android 4.4.
There is developed a module for solving this. But, I found advice here in another topic
Just add borderRadius property with a minimum value. Sample code:
var webview = Ti.UI.createWebView({url: '..', borderRadius: 1});
I'm trying to load a image from users phone, crop it and then display. Im using the webview plugin to do that. It works as intended on android but not on IOS.
I've tried this from another question, which resloves to file not found error
itemSrc = itemSrc.replace(/^file:\/\//, '');
I also looked at NormalizeURL but that does not seem to work with Ionic 4
Heres some code
this.imagePicker.getPictures(options)
.then((results: string[]) => {
results.forEach(res => {
this.crop.crop(res, {quality: 50})
.then(
data =>{
//this is extracting the URL
this.user.photos.push(this.webview.convertFileSrc(data));
},
After that, the UI should display the cropped image, which it does on android, but not on IOS.
I used safari dev tools to inspect and this is the error:
[Error] Failed to load resource: unsupported URL (unsafe:ionic://localhost/_app_file_/Users/radmac/Library/Developer/CoreSimulator/Devices/8E6A6BFA-66FA-4DB3-B556-BCE9E2EFE33A/data/Containers/Data/Application/C39D8D99-0F67-4D33-9195-EE2B4D4E4707/tmp/cdv_photo_024.jpg, line 0)
So, I found the solution for this. Before that, You can read this blog post which is really helpful if you want to understand more about ionic native and images.
https://ionicframework.com/blog/storing-photos-with-the-cordova-camera-and-file-plugins/
the solution was to just wrap the webview converted src with dom sanitizer, like so,
const resolvedImg = this.webview.convertFileSrc(data);
this.user.photos.push(<string>this.sanitizer.bypassSecurityTrustUrl(resolvedImg));
Make sure to import the dom sanitizer.
import {DomSanitizer} from "#angular/platform-browser";
...
constructor(private sanitizer: DomSanitizer){
...
}
I have a quite typical problem of laggy animations during component rendering. However, as far as I understand, the common solutions I found in the documentation of react-native cannot be applied to my use case.
Let me explain: I have a tab pager implemented with (i) a ViewPagerAndroid containing a set of pages and (ii) a tab bar composed of a set of touchables and a line (Animated.View) that moves (translateX transform) when the pager X-scroll value changes.
Each page component follows the same logic:
when componentDidMount is called, it triggers a network call for loading data
once the data are loaded, the state is updated with the new data and the component is rerendered
the render method simply returns a FlatList that displays the loaded data (20 items only)
My problem is: if the user clicks on a tab while the pages are rendered, the animations are horribly laggy. Given that the animation and the rerendering are performed on the UI thread, I'm guessing that they are competing in some way.
I eliminated various causes, but wasn't able to find a proper solution to keep the animation fluid:
I replaced the network call with hardcoded data and a simple timeout; the UI is still laggy when the pages are rerendered
I tried to improve the rerendering time, but the FlatList is quite slow even using pure components.
I tried in release mode and there is no differences
The problem occurs also on a physical device (Nexus 5X, which is quite powerful)
It's not specific to my implementation, I tried github.com/skv-headless/react-native-scrollable-tab-view and github.com/zbtang/React-Native-ViewPager
I know about InteractionManager and TimerMixin.requestAnimationFrame, but it's useless in my case: when the rendering is started, the user can still click on the tab bar buttons and it's not an option to wait the end of the render (laggy).
I uploaded my code in a github repository (https://github.com/benjaminbillet/tabbartest), in case you want to have more details. It's quite straightforward, but don't hesitate to ask me more details.
Some additional information:
react-native 0.46.4
node 8.2.0
npm 5.3.0
tried only on Android.
Do you think I should fill a bug report?
Thanks a lot.
EDIT-1 Here is a simplified version of the animation code:
render() {
const underlineStyle = {
position: 'absolute',
left: 0,
bottom: 0,
width: this.tabWidth,
height: underlineHeight,
backgroundColor: underlineColor,
transform: [{
translateX: this.pagerScrollX.interpolate({
inputRange: [0, 1],
outputRange: [0, this.tabWidth],
}),
}],
};
return (
<View style={[styles.tabs, style]}>
...
<Animated.View style={underlineStyle} />
</View>
);
}
onPageScroll(offset) {
const { offset, position } = e.nativeEvent;
this.pagerScrollX.setValue(position + offset);
}
Good day mates,
I'm currently having a problem with our project. I'd like to rerender a pdf with fields to contain texts and a signature, are there any ways or solution available to get this?
Please direct me to the right direction. :D
Did you try react-native-view-pdf package? It's pretty simple and has zero NPM dependencies:
import PDFView from 'react-native-view-pdf';
<View style={{ flex: 1 }}>
<PDFView
style={{ flex: 1 }}
onError={(error) => console.log('onError', error)}
onLoad={() => console.log('PDF rendered from url')}
resource="http://www.pdf995.com/samples/pdf.pdf"
resourceType="url"
/>
</View>
Recently i did a similar research for our java-webapp. Those may be useful in your case also:
You can use Flying Saucer to convert your XHTML based template
into PDF (CSS2.1 supported - you'll be able to render really pretty
PDFs)
If HTML and CSS are not your strengths - stick with Apache FOP.
As an experimental solution - you can try to generate those on
client-side with jsPDF (for simplistic stuff this approach may
do it)
In the end we chose Flying Saucer and we're pretty happy with the results
try this react-native-pdf-view on github