Add Pattern Painters Support for BarChart (Stripes, Dots, Squares)#1958
Add Pattern Painters Support for BarChart (Stripes, Dots, Squares)#1958Caffo17 wants to merge 8 commits intoimaNNeo:mainfrom
Conversation
|
Hi, thanks for your contribution. I really like the idea. |
|
Hi @imaNNeo, I managed to get the same result using FragmentShaders but I'm not sure how to test them. I'm working on it. |
Showcase with shadersSimulator.Screen.Recording.-.iPhone.16.Pro.-.2025-08-03.at.19.29.06.mp4 |
|
That looks amazing! 🤩
Please let me know what you think. |
Removed FlShaderManager and replaced patternPainter with surfacePainter in BarChartRodData. Refactored pattern painter classes to extend FlSurfacePainter, added initialization logic, and updated related usages and tests. Renamed fl_shader_painter.dart to fl_surface_painter.dart and updated exports. Added dedicated shader tests and removed obsolete manager tests.
|
Hi @imaNNeo, thanks for your feedback. I've made the changes you asked for. Let me know what you think about them. |
|
Hi @imaNNeo , sorry for the ping. Could you check the last changes? Thanks 🙏 |
| FlSurfacePainter({required this.flShader}); | ||
|
|
||
| /// {@macro fl_shader} | ||
| final FlShader flShader; |
There was a problem hiding this comment.
I think we can use a generic abstraction for this part, like:
abstract class FlSurfacePainter<S extends FlShader> extends CustomPainter {
FlSurfacePainter({required this.flShader});
/// {@macro fl_shader}
final S flShader;
/// Initializes the painter by setting up the shader.
Future<void> initialize() async {
await flShader.init();
}
/// Returns whether the shader is initialized.
bool get isInitialized => flShader.isInitialized;
}And also, for the Painters, I think we can remove the shader parameter, we can just instantiate it to make it simpler, like:
class StripesPatternPainter extends FlSurfacePainter<StripesShader> {
StripesPatternPainter({
this.color = Colors.black,
this.width = 2,
this.gap = 4,
this.angle = 45,
}) : super(flShader: StripesShader());And from the user's perspective, it can be like:
final stripesPainter = StripesPatternPainter(
width: 2,
gap: 8,
angle: 45,
);
@override
void initState() {
super.initState();
initializeShaders();
}
Future<void> initializeShaders() async {
await stripesPainter.initialize();
}So I think this change improves the developer experience and makes it more expandable
There was a problem hiding this comment.
This approach makes the flShader initialization untestable.
We can inject a mock shader via an optional parameter, falling back to the default implementation when not provided:
StripesPatternPainter({
@visibleForTesting StripesShader? mockShader,
this.color = Colors.black,
this.width = 2,
this.gap = 4,
this.angle = 45,
}) : super(flShader: mockShader ?? StripesShader());What do you think?
|
And lastly, I think we can also add the |
|
Hi @imaNNeo, You can check the changes |
|
Hey any updates on when this could be merged? I am currently using my approach of what I had implmented and indeed it does seem to have some performance issues when the datasets are large. |
This PR introduces support for custom pattern painters in the
BarChartcomponent, allowing each bar to be rendered with a configurable pattern. The following features and improvements are included:CustomPainterclasses for bar patterns:StripesPatternPainter: Draws diagonal, vertical, or horizontal stripes at a configurable angle.CirclePoisPatternPainter: Draws a polka dot (circle) pattern.SquarePoisPatternPainter: Draws a polka dot (square) pattern.BarChartRodDatanow accepts apatternPainterproperty. If set, the bar will be rendered using the provided pattern.bar_chart_sample1.dart) to allow users to select and preview different bar patterns via a dropdown.Motivation
These changes make it easy to add visual variety to bar charts, supporting use cases such as accessibility, branding, and improved data distinction. The new pattern painters are fully customizable and integrate seamlessly with the existing chart API. Related to this issue.
Showcase
showcase_compressed.mp4