DEV Community

Cover image for Rendering Gradient Lines in LineChart Using `react-native-chart-kit`
Muhammad Tayyab Sheikh
Muhammad Tayyab Sheikh

Posted on

Rendering Gradient Lines in LineChart Using `react-native-chart-kit`

Hello Dev Community! 👋

Today, I’m excited to share a neat trick on how to enhance your LineCharts with gradient lines using react-native-chart-kit. This technique will make your data visualizations more appealing, whether you’re tracking fitness progress, visualizing sales trends, or displaying any other kind of data.

Step-by-Step Guide

1. Setting Up Your Custom LineChart Component

To begin, we’ll create a custom component by extending the LineChart component from react-native-chart-kit. This will allow us to override methods and introduce our gradient lines.

import React from 'react';
import { LineChart } from 'react-native-chart-kit';
import { AbstractChartConfig } from 'react-native-chart-kit/dist/AbstractChart';
import { LinearGradient, Path, Stop } from 'react-native-svg';

class CustomLineChart extends LineChart {
  getNonBezierLinePoints = (dataset, _a) => {
    const { width, height, paddingRight, paddingTop, data } = _a;
    if (dataset.data.length === 0) {
      return 'M0,0';
    }
    const datas = this.getDatas(data);
    const xMax = this.getXMaxValues(data);
    const x = (i) => Math.floor(paddingRight + (i * (width - paddingRight)) / xMax);
    const baseHeight = this.calcBaseHeight(datas, height);
    const y = (i) => {
      const yHeight = this.calcHeight(dataset.data[i], datas, height);
      return Math.floor(((baseHeight - yHeight) / 4) * 3 + paddingTop);
    };
    return ['M' + x(0) + ',' + y(0)].concat(
      dataset.data.slice(1).map((_, i) => 'L' + x(i + 1) + ',' + y(i + 1))
    ).join(' ');
  };

  renderLine = ({ width, height, paddingRight, paddingTop, data }) => {
    const output = [];
    if (!data) return [];

    data.forEach((dataset, index) => {
      const bezierPoints = this.props.bezier
        ? this.getBezierLinePoints(dataset, { width, height, paddingRight, paddingTop, data })
        : this.getNonBezierLinePoints(dataset, { width, height, paddingRight, paddingTop, data });

      const gradientColors = ['#FDCC3A', '#FA3431'];

      output.push(
        <LinearGradient key={`line-gradient-${index}`} id={`line-gradient-${index}`} x1="0%" y1="0%" x2="100%" y2="0%">
          <Stop offset="0%" stopColor={gradientColors[0]} />
          <Stop offset="100%" stopColor={gradientColors[1]} />
        </LinearGradient>,
        <Path
          key={`line-${index}`}
          d={bezierPoints}
          fill="none"
          stroke={`url(#line-gradient-${index})`}
          strokeWidth={this.getStrokeWidth(dataset)}
          strokeDasharray={dataset.strokeDashArray}
          strokeDashoffset={dataset.strokeDashOffset}
        />
      );
    });

    return output;
  };
}

export default CustomLineChart;
Enter fullscreen mode Exit fullscreen mode

2. Overriding the renderLine Method

The renderLine method is crucial as it controls how the lines are drawn on the chart. By overriding this method, we can customize the rendering process to include gradient strokes.

3. Defining the Gradient

We use LinearGradient and Stop from react-native-svg to define the gradient. This involves specifying the colors and their positions within the gradient.

4. Rendering the Lines with Gradients

We modify the Path component to use the gradient definition in its stroke attribute. This change ensures that the lines are drawn with the specified gradient.

Putting It All Together

Here’s the complete code for our custom LineChart component:

import React from 'react';
import { LineChart } from 'react-native-chart-kit';
import { AbstractChartConfig } from 'react-native-chart-kit/dist/AbstractChart';
import { LinearGradient, Path, Stop } from 'react-native-svg';

class CustomLineChart extends LineChart {
  getNonBezierLinePoints = (dataset, _a) => {
    const { width, height, paddingRight, paddingTop, data } = _a;
    if (dataset.data.length === 0) {
      return 'M0,0';
    }
    const datas = this.getDatas(data);
    const xMax = this.getXMaxValues(data);
    const x = (i) => Math.floor(paddingRight + (i * (width - paddingRight)) / xMax);
    const baseHeight = this.calcBaseHeight(datas, height);
    const y = (i) => {
      const yHeight = this.calcHeight(dataset.data[i], datas, height);
      return Math.floor(((baseHeight - yHeight) / 4) * 3 + paddingTop);
    };
    return ['M' + x(0) + ',' + y(0)].concat(
      dataset.data.slice(1).map((_, i) => 'L' + x(i + 1) + ',' + y(i + 1))
    ).join(' ');
  };

  renderLine = ({ width, height, paddingRight, paddingTop, data }) => {
    const output = [];
    if (!data) return [];

    data.forEach((dataset, index) => {
      const bezierPoints = this.props.bezier
        ? this.getBezierLinePoints(dataset, { width, height, paddingRight, paddingTop, data })
        : this.getNonBezierLinePoints(dataset, { width, height, paddingRight, paddingTop, data });

      const gradientColors = ['#FDCC3A', '#FA3431'];

      output.push(
        <LinearGradient key={`line-gradient-${index}`} id={`line-gradient-${index}`} x1="0%" y1="0%" x2="100%" y2="0%">
          <Stop offset="0%" stopColor={gradientColors[0]} />
          <Stop offset="100%" stopColor={gradientColors[1]} />
        </LinearGradient>,
        <Path
          key={`line-${index}`}
          d={bezierPoints}
          fill="none"
          stroke={`url(#line-gradient-${index})`}
          strokeWidth={this.getStrokeWidth(dataset)}
          strokeDasharray={dataset.strokeDashArray}
          strokeDashoffset={dataset.strokeDashOffset}
        />
      );
    });

    return output;
  };
}

export default CustomLineChart;
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following these steps, you can easily add gradient lines to your LineCharts in React Native. This not only enhances the visual appeal of your charts but also makes your data representation more engaging. Feel free to tweak the gradient colors and other properties to match your app’s theme and make your charts even more impressive!

If you found this tutorial helpful, please share it with your network. Happy coding! 👨‍💻👩‍💻


Feel free to leave comments and let me know how you are using this technique in your projects!

Top comments (0)