Rendering Gradient Lines in LineChart Using `react-native-chart-kit`
Muhammad Tayyab Sheikh
Posted on July 25, 2024
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;
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;
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!
Posted on July 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.