I need to create an arc chart as following:
Using canvas I've created this one:
My code:
class CustomChartPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Rect drawingRect = Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2);
final Paint paint2 = Paint();
paint2.color = const Color.fromRGBO(0, 0, 0, 0.04);
paint2.style = PaintingStyle.stroke;
paint2.strokeWidth = 50;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), size.width / 2, paint2);
canvas.drawArc(drawingRect,
-pi / 2 + 0.35,
pi - 0.35,
false,
greenPaint);
canvas.drawArc(drawingRect,
pi / 2 + 0.35,
pi - 0.35,
false,
orangePaint);
}
}
How can I round edges of arcs as presented on the first picture?
As #pskink mentioned, the solution is to use Paint.strokeCap, more precisely: paint.strokeCap = StrokeCap.round
Related
How to implement effect like pic below.
I have a rect container(width:400, height:100), I want to clip the blue area of the rect, so I can get the orange area.Attention,
The orange arc is tangent to the bottom line . Could you give the details code?
You can use a Custom Clipper class , to get this type of shape I will share an example code you can change values according to your need
class ClipPathClass extends CustomClipper<Path> {
#override
Path getClip(Size size) {
double radius = 50;
var path = Path();
path.lineTo(0.0, size.height - 30);
var firstControlPoint = Offset(size.width / 4, size.height);
var firstPoint = Offset(size.width / 2, size.height);
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstPoint.dx, firstPoint.dy);
var secondControlPoint = Offset(size.width - (size.width / 4), size.height);
var secondPoint = Offset(size.width, size.height - 30);
path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
secondPoint.dx, secondPoint.dy);
path.lineTo(size.width, 0.0);
path.lineTo(size.width - radius, 0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
then use this ClipPathClass() like ,
ClipPath(
clipper: ClipPathClass(),
child: Container(width:400,height: 100,color:Colors.grey)
)
I need help, I am trying to google to find out how I can implement a dotted path in canva when using canva.drawPath. I can only see code of canva.drawLine, But I can't find for canva.drawPath. Please see the code below.
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
class CustomPainterWeb extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
double dashHeight = 5, dashSpace = 3, startY = 0;
var paint = Paint();
var path = Path();
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 0.5;
paint.color = HexColor("#718096");
// First service curve
path.moveTo(size.width / 5.0, size.height / 4.2);
path.cubicTo(size.width / 5.0, size.height / 2.3, size.width / 2.0,
size.height / 3.6, size.width / 2.0, size.height / 2.3);
// First service arrow
path.moveTo(size.width / 2.0, size.height / 2.29);
path.lineTo(size.width / 1.96, size.height / 2.34);
path.moveTo(size.width / 2.0, size.height / 2.29);
path.lineTo(size.width / 2.04, size.height / 2.34);
// Second service curve
path.moveTo(size.width / 1.8, size.height / 1.8);
path.cubicTo(size.width / 1.8, size.height / 1.3, size.width * 0.3,
size.height * 0.6, size.width * 0.3, size.height / 1.3);
// second service arrow
path.moveTo(size.width * 0.30, size.height / 1.3);
path.lineTo(size.width * 0.29, size.height / 1.32);
path.moveTo(size.width * 0.299, size.height / 1.3);
path.lineTo(size.width * 0.31, size.height / 1.32);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
I am searching for a package in flutter where I can create a chart with an interactable graph, where I can manipulate data with drag and drop
Example:
An example chart
Now I want to ajust each value in that step diagram with drag and drop (up and down)
I found high charts and some of my collegues used that to do so but not in flutter so im not sure if that is possible there.
Firstly, It's totally possible to create interactive charts with Flutter.
You can either implement it yourself with a CustomPainter and some widgets.
Here's an example of a Curved basic chart.
CustomPaint(
painter: CurveBackground(color: \\ yourColor),
child: \\ your child
)
class CurveBackground extends CustomPainter {
final Color color;
CurveBackground({this.color});
#override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = color;
paint.style = PaintingStyle.fill;
var path = Path();
path.moveTo(0, Dimens.size_30());
path.quadraticBezierTo(size.width * 0.4, size.height * 0.1,
size.width * 0.3, size.height * 0.3);
path.quadraticBezierTo(size.width * 0.1, size.height * 0.6,
size.width * 0.45, size.height * 0.7);
path.quadraticBezierTo(
size.width * 1, size.height * 0.9, size.width * 0.9, size.height * 1.0);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
You can also check out some specialized packages as: syncfusion_flutter_charts
I think you'll be interested in the step_line chart.
How do you rotate an object drawn on a canvas in Flutter (not the whole canvas, just the object)?
The following does not work. Error is: This expression has a type of 'void' so its value can't be used.
Transform.rotate(
angle: pi,
child: canvas.drawPath(
getTrianglePath(Offset(secondhandX, secondhandY)),
secondhandBrush));
Here is the full code:
// imports omitted
class TimerDialPainter extends CustomPainter {
Path getTrianglePath(Offset position) {
return Path()
..moveTo(position.dx - 20, position.dy - 20)
..lineTo(position.dx + 40, position.dy + 40)
..lineTo(position.dx - 20, position.dy + 40)
..lineTo(position.dx - 20, position.dy - 20);
}
#override
void paint(Canvas canvas, Size size) {
int centerX = size.width / 2;
int centerY = size.height / 2;
int secondsArc = 60;
Paint countBrush = Paint()
..color = (Colors.red)
..style = PaintingStyle.fill
..strokeWidth = 3;
var secondhandX = centerX + 80 * cos(secondsArc * pi / 180);
var secondhandY = centerY + 80 * sin(secondsArc * pi / 180);
Transform.rotate(
angle: pi/3,
child: canvas.drawPath(
getTrianglePath(Offset(secondhandX, secondhandY)),
countBrush));
} //I feel this is not a right place to solve this??
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Try rotating the canvas and paint it. Then rotate it back to previous value
#override
void paint(Canvas canvas, Size size) {
double centerX = size.width / 2;
double centerY = size.height / 2;
int secondsArc = 60;
Paint countBrush = Paint()
..color = (Colors.red)
..style = PaintingStyle.fill
..strokeWidth = 3;
num secondhandX = centerX + 80 * cos(secondsArc * pi / 180);
num secondhandY = centerY + 80 * sin(secondsArc * pi / 180);
canvas.rotate(40);
canvas.drawPath(
getTrianglePath(Offset(secondhandX.toDouble(), secondhandY.toDouble())),
countBrush);
canvas.rotate(0);
}
I'm currently blocked trying to create a widget (like a tooltip box) that is represented by the image below. I should probably be able to create it by relying on a Painter class, but i'm not familiar doing so...
https://pasteboard.co/IgccNxD.png
(it's small, yes, max height = ~35px)
The code ended being something like:
void paint(Canvas canvas, Size size) {
Paint p = Paint()
..color = Colors.red
..isAntiAlias = true
..style = PaintingStyle.fill;
Offset nw = Offset(0, 0);
Offset se = Offset(size.width, size.height * 0.8);
final Rect rect = Rect.fromPoints(nw, se);
final RRect r = RRect.fromRectAndRadius(rect, Radius.circular(10));
canvas.drawRRect(r, p);
Offset bottomPoint = Offset((size.width / 2), size.height);
Offset rightPoint = Offset((size.width / 2) * 0.80, size.height * 0.80);
Offset leftPoint = Offset((size.width / 2) * 1.20, size.height * 0.80);
var path1 = Path()
..moveTo(rightPoint.dx, rightPoint.dy)
..lineTo(bottomPoint.dx, bottomPoint.dy)
..lineTo(leftPoint.dx, leftPoint.dy)
..lineTo(rightPoint.dx, rightPoint.dy);
canvas.drawPath(path1, p);
}
For the text inside, I've stacked it above this painting.