Reputation: 1
i created chart with custom painter but the problem is i want to set chartbar height fix but the fill color of chart show in entire screen how can i crop upper part of container based on char curves
is possible to cut container same as chart curves
current chart
like this
Chartbar code :
// CustomPainter class to draw a curved chart
class CurvedChartPainter extends CustomPainter {
// Properties to configure the chart
final List<Map<String, double>> xValues;
final List<Map<String, double>> yValues;
final Color? color;
final double strokeWidth;
final List<Color> gradientColors;
final List<double> gradientStops;
final TextStyle labelTextStyle;
// Constructor
CurvedChartPainter({
required this.xValues,
required this.yValues,
required this.strokeWidth,
this.color,
this.gradientColors = const [
Color(0x00F63E02),
Color(0xFFFFFFFF),
],
this.gradientStops = const [0.0, 1.0],
this.labelTextStyle = const TextStyle(color: Colors.grey, fontSize: 12),
});
// The paint method is called when the custom painter needs to paint
@override
void paint(Canvas canvas, Size size) {
// Set up the paint for the chart line
var paint = Paint();
paint.color = color ?? const Color(0xFFF63E02);
paint.style = PaintingStyle.stroke;
paint.strokeWidth = strokeWidth;
// Set up the paint for the chart fill
var fillPaint = Paint();
fillPaint.style = PaintingStyle.fill;
// Set up the paint for the axes
var axisPaint = Paint()
..color = Colors.grey
..style = PaintingStyle.stroke
..strokeWidth = 1.0;
// Create paths for the chart line and fill
var path = Path();
var fillPath = Path();
// Check if there are enough values to draw the chart
if (xValues.length > 1 && yValues.isNotEmpty) {
// Calculate some initial values
final maxValue = yValues.last.values.last;
final firstValueHeight = size.height * (xValues.first.values.first / maxValue);
// Initialize the paths with the first point
path.moveTo(0.0, size.height - firstValueHeight);
fillPath.moveTo(0.0, size.height);
fillPath.lineTo(0.0, size.height - firstValueHeight);
// Calculate the distance between each x value
final itemXDistance = size.width / (xValues.length - 1);
// Loop through the x values and draw the chart line and fill
for (var i = 1; i < xValues.length; i++) {
final x = itemXDistance * i;
final valueHeight = size.height - strokeWidth - ((size.height - strokeWidth) * (xValues[i].values.elementAt(0) / maxValue));
final previousValueHeight = size.height - strokeWidth - ((size.height - strokeWidth) * (xValues[i - 1].values.elementAt(0) / maxValue));
// Draw a quadratic bezier curve between each point
path.quadraticBezierTo(
x - (itemXDistance / 2) - (itemXDistance / 8),
previousValueHeight,
x - (itemXDistance / 2),
valueHeight + ((previousValueHeight - valueHeight) / 2),
);
path.quadraticBezierTo(
x - (itemXDistance / 2) + (itemXDistance / 8),
valueHeight,
x,
valueHeight,
);
// Draw the fill path using the same quadratic bezier curves
fillPath.quadraticBezierTo(
x - (itemXDistance / 2) - (itemXDistance / 8),
previousValueHeight,
x - (itemXDistance / 2),
valueHeight + ((previousValueHeight - valueHeight) / 2),
);
fillPath.quadraticBezierTo(
x - (itemXDistance / 2) + (itemXDistance / 8),
valueHeight,
x,
valueHeight,
);
}
// Close the fill path
fillPath.lineTo(size.width, size.height);
fillPath.close();
}
// Create a gradient for the fill
LinearGradient gradient = LinearGradient(
colors: gradientColors,
stops: gradientStops,
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
);
Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
fillPaint.shader = gradient.createShader(rect);
// Draw the fill path with the gradient
canvas.drawPath(fillPath, fillPaint);
// Draw the chart line
canvas.drawPath(path, paint);
}
used like this with stack
// Build method to generate the widget tree
@override
Widget build(BuildContext context) {
// Define the X axis values for the chart
// String will be text label and double will be value in the Map<String, double>
final List<Map<String, double>> xValues = [
{"day 1": 80.0},
{"day 2": 50.0},
{"day 3": 30.0},
{"day 4": 50.0},
{"day 5": 10.0},
{"day 6": 0.0},
{"day 7": 100.0},
];
// Define the Y axis values for the chart
// String will be text label and double will be value in the Map<String, double>
final List<Map<String, double>> yValues = [
{"0": 0.0},
{"20": 20.0},
{"40": 40.0},
{"60": 60.0},
{"80": 80.0},
{"100": 100.0},
];
// Define the stroke width for the chart line
const stroke = 3.0;
// Return a SizedBox to limit the size of the chart
return Stack(
children: [
Container(
height: double.infinity,
width: double.infinity,
color: blue2,
),
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.2,
// Use CustomPaint to draw the curved chart
child: CustomPaint(
painter: CurvedChartPainter(
color: blue5,
// Set the color of the chart line
yValues: yValues,
// Pass the Y axis values
strokeWidth: stroke,
// Set the stroke width
xValues: xValues,
// Pass the X axis values
gradientStops: [0.22, 063],
gradientColors: [
// Define the gradient colors for the chart fill
calenderLinearGradient2.withOpacity(0.46),
blue1.withOpacity(0),
],
),
),
),
],
);
}
Upvotes: 0
Views: 32