DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • How to Build a React Native Chat App for Android
  • Best Gantt Chart Libraries for React
  • Optimizing User Experience in React Native

Trending

  • How to Submit a Post to DZone
  • Docker Base Images Demystified: A Practical Guide
  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • Unlocking AI Coding Assistants Part 4: Generate Spring Boot Application
  1. DZone
  2. Coding
  3. JavaScript
  4. Using Recharts in React Native project

Using Recharts in React Native project

A developer shows us how to use this React library, made using React and D3, to create a chart application for standard and mobile browsers.

By 
Tho Luong user avatar
Tho Luong
DZone Core CORE ·
Dec. 06, 17 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
24.2K Views

Join the DZone community and get the full member experience.

Join For Free

1. Introduction to Recharts

Recharts is a chart library built with React and D3. Recharts supports many kinds of charts such as Area Chart, Bar Chart, Line Chart, and Pie Chart. The strength of Recharts is easy to extend and customize. For example, we can change the active cursor, legend, and tick in Axises to our own component and styling. The following is an example of how to customize a tick on the X Axis:

const CustomizedAxisTick = React.createClass({
  render () {
    const {x, y, stroke, payload} = this.props;
   return <g>
        <text x={0} y={0} dy={16} textAnchor="end" 
            fill="#666" transform="rotate(-35)">
            {payload.value}
        </text>
    </g>
  }
});

const SimpleLineChart = React.createClass({
  render () {
    return <LineChart>
        <XAxis dataKey="name" tick={<CustomizedAxisTick/>}/>
        <YAxis/>
        <CartesianGrid />
        <Line type="monotone" dataKey="pv" />
    </LineChart>
  }
});

Find more examples here and the full Recharts API here.

2. Project Structure

In my React Native project, I add a ‘web' directory for a React project which uses the Recharts library:

Image title

In development, web part runs at port 9000 and is loaded by the Webview Bridge component in the React Native part. I chose Webview Bridge over built-in Webview because it supports communication between React Native and the web. For example, when a user clicks on a custom button in a chart component we want to change the screen to another scene or when they click on the Navigation Button, the chart content will be changed. All of these things can be done with Webview Bridge. Below is an example of how to work with Webview Bridge:

Using web parts, listen and send a message to the React Native part:

if (WebViewBridge) {
    WebViewBridge.onMessage = function (message) {
        console.log(message)
    };
    WebViewBridge.send("hello from webview");
}

In the React Native part, listen and send a message to web parts:

let Sample = React.createClass({
    onBridgeMessage(message) {
        const { webviewbridge } = this.refs;
        switch (message) {
            case "hello from webview":
                webviewbridge.sendToBridge("hello from react-native");
                break;
        }
    },
    render() {
        return <WebViewBridge
            ref="webviewbridge"
            onBridgeMessage={this.onBridgeMessage.bind(this)}
            source={{uri: "http://localhost:9000"}}
        />
  }
});

3. Responsive Design for Charts

To make the app work with a wide range of devices, charts must be built with a responsive design. In the ChartPage component, we need to listen for a “window resize” event and store the screen width in the component state:

componentWillMount() {
    this.props.getPoints();
    $(window).resize(() => {
        this.setState({
            chartWidth: $(window).width()
        });
    });
    // fire resize:
    $(window).trigger('resize');
}

chartWidth will be set with width property to render a responsive chart in the ChartPage.renderChart function:

// File: web/ui/page/ChartPage.jsx
let props = {
    width:this.state.chartWidth,
    height: this.state.chartHeight,
    lock: this.handleLock.bind(this),
    unlock: this.handleUnlock.bind(this),
    margin: {top: 5, right: MARGIN_RIGHT, left: 0, bottom: 5}
}
if(chartConfig.type != 'pie') {
    props.data = this.props.stats.points[chartConfig.dataKey];
}
return <div key={'chart-' + chartConfig.dataKey} className='gt-chart'>
    <div className='gt-tooltip-contents'>
        <span className='header'>{label}</span>
    </div>
    <Chart {...props}>
        {this.renderChartBody(chartConfig)}
    </Chart>
</div>

And unregister before component unmount:

// File: web/ui/page/ChartPage.jsx
componentWillUnmount() {
    $(window).off('resize');
}

After all that, here’re the results:

Line Chart and Bar Chart:

Image title

Area Chart and Pie Chart:

Image title

4. Patch Recharts to Support iOS Gesture

There's a difference between touch gesture in iOS and Android. In Android, Webview components can react with both vertical and horizontal at the same time, but in iOS, it cannot. This makes moving your chart cursor in iOS very difficult. If the user touches and moves the cursor a bit vertically, it will turn the move to Webview scrollbar instead of keeping the chart cursor moving.

My solution is to patch Recharts to lock the Webview scrollbar while the user is using the chart cursor and to release it when they finish. In the file web/ui/components/recharts/generateCategoricalChart.js, I added some functions to listen to touch events to detect whether the user is using a chart cursor or not. If they start using a chart cursor, send a lock message to Webview Bridge:

// File: web/ui/components/recharts/generateCategoricalChart.js
this.handleTouchMove = function (e) {};
this.handleTouchStart = function(e) {}
this.handleTouchEnd = function() {}

this.lock = function() {
    window.locked = true;
    if(self.props.lock != null) {
        self.props.lock();
    }
}

this.unlock = function() {
    window.locked = false;
    if(self.props.unlock != null) {
        self.props.unlock();
    }
}

In ChartScreen.js, store the 'locked' value in the component state and set it to WebViewBridge.scrollEnabled:

// File: screens/ChartScreen.js
render() {
    let contentInset = {
        right: -1 * config.chartScrollbarWidth,
        top: 0,
        bottom: 0,
        left: 0
    }
    let browserStyle = {
        ...styles.browser,
    }
    if(!this.state.loaded) {
        browserStyle.opacity = 0;
    }
    let browser = <WebViewBridge
        contentInset={contentInset}
        source={{uri: this.buildUrl()}}
        style={browserStyle}
        scrollEnabled={!this.state.locked}
        onLoadEnd={this.handleLoadEnd.bind(this)}
        onBridgeMessage={this.handleBridgeMessage.bind(this)}
        startInLoadingState={false}
    />;
    return <View style={styles.container}>
        {browser}
    </View>
}

Run web/patch-recharts.sh to replace the original generateCategoricalChart.js file in the Recharts library.

5. Deployment

If your app is an analysis app with many charts, I recommend you to deploy web parts in a server and load it in React Native remotely. By doing this, when the charts are updated, the user doesn't need to reinstall the app to have the latest version of charts. Otherwise, if the chart is only a small part of the app, you should build the web part then load index.html and bundle.js from internal device file system.

6. My Project

Visit and fork my project at https://github.com/thoqbk/RNCharts or contact me by thoqbk@gmail.com for further information.

React Native React (JavaScript library) Chart

Published at DZone with permission of Tho Luong. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • How to Build a React Native Chat App for Android
  • Best Gantt Chart Libraries for React
  • Optimizing User Experience in React Native

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!