Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Margin property with some other changes #11

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MyApp extends StatelessWidget {
primaryColor: const Color(0xFF0C00C5),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
backgroundColor: WidgetStateProperty.all<Color>(
const Color(0xFF0C00C5),
),
),
Expand Down
46 changes: 37 additions & 9 deletions example/lib/sample1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@ import 'package:intl/intl.dart';
class Sample1 extends StatelessWidget {
const Sample1({Key? key}) : super(key: key);

List<List<LineChartSpot>> get spotsList => [
[
const LineChartSpot(0.0, 3.7806739187454177),
const LineChartSpot(1.0, 3.5991452613605475),
const LineChartSpot(2.0, 2.6534102643618773),
const LineChartSpot(3.0, 3.495803225491705),
const LineChartSpot(4.0, 3.2687418283157106),
], [
const LineChartSpot(0.0, 7.748415631185418),
const LineChartSpot(1.0, 6.876026011448352),
const LineChartSpot(2.0, 7.62484251992211),
const LineChartSpot(3.0, 8.320701383214557),
const LineChartSpot(4.0, 8.34446381632569),
], [
const LineChartSpot(0.0, 1.8119931114678556),
const LineChartSpot(1.0, 2.119198907823737),
const LineChartSpot(2.0, 2.907415228279169),
const LineChartSpot(3.0, 2.0087045168815028),
const LineChartSpot(4.0, 2.675884068457985),
],[
const LineChartSpot(0.0, 3.4873266523791857),
const LineChartSpot(1.0, 4.446586791105186),
const LineChartSpot(2.0, 4.223622629086266),
const LineChartSpot(3.0, 4.191570249574648),
const LineChartSpot(4.0, 4.7799742234986695),
],
];

@override
Widget build(BuildContext context) {
final today = DateTime.now();
Expand All @@ -20,7 +48,6 @@ class Sample1 extends StatelessWidget {
mainAxisSpacing: 16,
),
itemBuilder: (context, index) {
final spotsList = createSpotsList(spotsNum: 1, length: 5);
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
Expand All @@ -32,16 +59,17 @@ class Sample1 extends StatelessWidget {
AspectRatio(
aspectRatio: 16 / 9,
child: LineChart(
margin: EdgeInsets.symmetric(vertical: 10, horizontal: 5),
data: LineChartData(
lineBarsData: spotsList
.map((spots) => LineChartBarData(
spots: spots,
color:
index % 2 == 0 ? Colors.orange : Colors.cyan,
point: const LineChartPoint(
type: LineChartPointType.circle,
),
))
.map((spots) =>
LineChartBarData(
spots: spots,
color: index % 2 == 0 ? Colors.orange : Colors.cyan,
point: const LineChartPoint(
type: LineChartPointType.circle,
),
))
.toList(),
area: const LineChartArea(
borderRadius: BorderRadius.vertical(
Expand Down
23 changes: 15 additions & 8 deletions lib/src/line_chart/line_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class LineChart extends ImplicitlyAnimatedWidget {
this.tooltip,
Duration swapAnimationDuration = const Duration(milliseconds: 250),
Curve swapAnimationCurve = Curves.linear,
this.margin = EdgeInsets.zero,
}) : super(
key: key,
duration: swapAnimationDuration,
Expand All @@ -34,6 +35,8 @@ class LineChart extends ImplicitlyAnimatedWidget {
/// The tooltip displayed when tapping the line chart.
/// When null, the tooltip is disabled.
final LineChartTooltip? tooltip;
///
final EdgeInsets margin;

@override
AnimatedWidgetBaseState<LineChart> createState() => _LineChartState();
Expand All @@ -56,6 +59,7 @@ class _LineChartState extends AnimatedWidgetBaseState<LineChart> {
tooltip: widget.tooltip,
width: constraints.maxWidth,
height: constraints.maxHeight,
margin: widget.margin,
);
},
),
Expand All @@ -82,21 +86,23 @@ class _Chart extends StatelessWidget {
this.tooltip,
required this.width,
required this.height,
this.margin = EdgeInsets.zero,
}) : super(key: key);
final NormalizedLineChartData data;
final LineChartTooltip? tooltip;
final double width;
final double height;
final EdgeInsets margin;

@override
Widget build(BuildContext context) {
final xLabel = data.xAxis.label;
final yLabel = data.yAxis.label;
final textScaleFactor = MediaQuery.of(context).textScaleFactor;
final textScale = MediaQuery.of(context).textScaler;
final xAxisHeight = data.xAxis.label?.height ??
_calculateLabelMaxOffset(xLabel, textScaleFactor).dy;
_calculateLabelMaxOffset(xLabel, textScale).dy;
final yAxisWidth = data.yAxis.label?.width ??
_calculateLabelMaxOffset(yLabel, textScaleFactor).dx;
_calculateLabelMaxOffset(yLabel, textScale).dx;

return Stack(
clipBehavior: Clip.none,
Expand All @@ -114,7 +120,7 @@ class _Chart extends StatelessWidget {
range: data.xAxis.range,
yAxisWidth: yAxisWidth,
padding: data.area?.padding,
textScaleFactor: textScaleFactor,
textScale: textScale,
),
child: const SizedBox.expand(),
),
Expand All @@ -131,7 +137,7 @@ class _Chart extends StatelessWidget {
painter: LineChartYLabelPainter(
label: yLabel,
range: data.yAxis.range,
textScaleFactor: textScaleFactor,
textScale: textScale,
),
child: const SizedBox.expand(),
),
Expand All @@ -146,6 +152,7 @@ class _Chart extends StatelessWidget {
child: CustomPaint(
painter: LineChartPainter(
data: data,
margin: margin,
),
child: const SizedBox.expand(),
),
Expand All @@ -161,14 +168,14 @@ class _Chart extends StatelessWidget {
yAxisWidth: yAxisWidth,
positionX: data.xAxis.range.position,
positionY: data.yAxis.range.position,
)
),
],
);
}

static Offset _calculateLabelMaxOffset(
LineChartLabel? label,
double textScaleFactor,
TextScaler textScale,
) {
if (label == null || label.texts == null || label.texts!.isEmpty) {
return Offset.zero;
Expand All @@ -177,7 +184,7 @@ class _Chart extends StatelessWidget {
(labelText) => createTextPainter(
text: labelText.text,
style: label.style,
textScaleFactor: textScaleFactor,
textScale: textScale,
),
);
final maxWidth =
Expand Down
16 changes: 8 additions & 8 deletions lib/src/line_chart/line_chart_label_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class LineChartXLabelPainter extends CustomPainter {
required this.range,
required this.yAxisWidth,
required this.padding,
required this.textScaleFactor,
required this.textScale,
});

/// The label to draw.
Expand All @@ -30,7 +30,7 @@ class LineChartXLabelPainter extends CustomPainter {
final EdgeInsets? padding;

/// The text scale factor.
final double textScaleFactor;
final TextScaler textScale;

@override
void paint(Canvas canvas, Size size) {
Expand All @@ -42,7 +42,7 @@ class LineChartXLabelPainter extends CustomPainter {
final textPainter = createTextPainter(
text: labelText.text,
style: label.style,
textScaleFactor: textScaleFactor,
textScale: textScale,
);
final pixelX = getPixelX(rect, range.ratio(labelText.position));
if (label.hideOverflowedLabels) {
Expand Down Expand Up @@ -81,7 +81,7 @@ class LineChartXLabelPainter extends CustomPainter {
oldDelegate.range != range ||
oldDelegate.yAxisWidth != yAxisWidth ||
oldDelegate.padding != padding ||
oldDelegate.textScaleFactor != textScaleFactor;
oldDelegate.textScale != textScale;
}
}

Expand All @@ -91,7 +91,7 @@ class LineChartYLabelPainter extends CustomPainter {
LineChartYLabelPainter({
required this.label,
required this.range,
required this.textScaleFactor,
required this.textScale,
});

/// The label to draw.
Expand All @@ -101,7 +101,7 @@ class LineChartYLabelPainter extends CustomPainter {
final LineChartYRangeInternal range;

/// The text scale factor.
final double textScaleFactor;
final TextScaler textScale;

@override
void paint(Canvas canvas, Size size) {
Expand All @@ -112,7 +112,7 @@ class LineChartYLabelPainter extends CustomPainter {
final textPainter = createTextPainter(
text: labelText.text,
style: label.style,
textScaleFactor: textScaleFactor,
textScale: textScale,
);
canvas
..save()
Expand All @@ -134,6 +134,6 @@ class LineChartYLabelPainter extends CustomPainter {
bool shouldRepaint(covariant LineChartYLabelPainter oldDelegate) {
return oldDelegate.label != label ||
oldDelegate.range != range ||
oldDelegate.textScaleFactor != textScaleFactor;
oldDelegate.textScale != textScale;
}
}
39 changes: 28 additions & 11 deletions lib/src/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ class LineChartPainter extends CustomPainter {
/// Creates [LineChartPainter].
LineChartPainter({
required this.data,
this.margin = EdgeInsets.zero,
});

/// The normalized data for painting the line chart.
final NormalizedLineChartData data;

/// To Apply margin around the chart plot points
final EdgeInsets margin;

static final Map<LineChartBarData, List<Offset>> _cachedOffsets = {};

@override
Expand Down Expand Up @@ -54,7 +58,7 @@ class LineChartPainter extends CustomPainter {
}

for (final barData in data.lineBarsData) {
_drawChart(canvas, rect, barData);
_drawChart(canvas, rect, barData, margin);
}

for (final barData in data.lineBarsData) {
Expand All @@ -64,6 +68,7 @@ class LineChartPainter extends CustomPainter {
rect,
barData,
barData.point?.fillColor ?? data.area?.color,
margin,
);
}
}
Expand All @@ -87,19 +92,30 @@ class LineChartPainter extends CustomPainter {

/// Creates the points for the line chart.
static List<Offset> createPlotPoints(
Rect rect,
LineChartBarData lineBarData,
) {
Rect rect,
LineChartBarData lineBarData,
EdgeInsets margin,
) {
if (_cachedOffsets.containsKey(lineBarData)) {
return _cachedOffsets[lineBarData]!;
}

final points = <Offset>[];
for (final spot in lineBarData.spots) {
final x = getPixelX(rect, spot.x);
final y = getPixelY(rect, spot.y);
var padding = lineBarData.point?.size ?? 0.0;
final adjustedTop = rect.top + margin.top;
final adjustedBottom = rect.bottom - margin.bottom;
for (var i = 0; i < lineBarData.spots.length; i++) {
final spot = lineBarData.spots[i];
final x = (i == 0)
? getPixelX(rect, spot.x) + padding + margin.left
: (i == lineBarData.spots.length - 1)
? getPixelX(rect, spot.x) - padding - margin.right
: getPixelX(rect, spot.x);
final y = adjustedTop +
((getPixelY(rect, spot.y) - rect.top) / rect.height) *
(adjustedBottom - adjustedTop);
points.add(Offset(x, y));
}
_cachedOffsets[lineBarData] = points;
return points;
}

Expand Down Expand Up @@ -143,14 +159,14 @@ class LineChartPainter extends CustomPainter {
}
}

static void _drawChart(Canvas canvas, Rect rect, LineChartBarData barData) {
static void _drawChart(Canvas canvas, Rect rect, LineChartBarData barData, EdgeInsets margin) {
final paintStroke = Paint()
..color = barData.color
..strokeWidth = barData.strokeWidth
..style = PaintingStyle.stroke
..strokeCap = barData.strokeCap;

final points = createPlotPoints(rect, barData);
final points = createPlotPoints(rect, barData, margin);

if (points.length == 1) {
canvas.drawCircle(
Expand Down Expand Up @@ -178,6 +194,7 @@ class LineChartPainter extends CustomPainter {
Rect rect,
LineChartBarData barData,
Color? color,
EdgeInsets margin,
) {
final paintCircle = Paint()
..color = color ?? Colors.transparent
Expand All @@ -189,7 +206,7 @@ class LineChartPainter extends CustomPainter {
..style = PaintingStyle.stroke
..strokeCap = barData.strokeCap;

final points = createPlotPoints(rect, barData);
final points = createPlotPoints(rect, barData, margin);
for (final point in points) {
canvas.drawCircle(point, barData.point!.size, paintCircle);
canvas.drawCircle(point, barData.point!.size, paintBorder);
Expand Down
4 changes: 2 additions & 2 deletions lib/src/utils/paint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import 'package:flutter/material.dart';
TextPainter createTextPainter({
required String text,
required TextStyle? style,
required double textScaleFactor,
required TextScaler textScale,
}) =>
TextPainter(
text: TextSpan(text: text, style: style),
textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor,
textScaler: textScale,
maxLines: 1,
)..layout();

Expand Down