From d2b7d6f23892ad1b59973be4e1dbbc7b474d601f Mon Sep 17 00:00:00 2001 From: terryl1900 Date: Mon, 15 Mar 2021 16:03:01 -0700 Subject: [PATCH 1/4] Set start/end point of TouchLine --- example/lib/line_chart/line_chart_page3.dart | 12 +++ .../samples/line_chart_sample9.dart | 99 +++++++++++++++++++ lib/src/chart/line_chart/line_chart_data.dart | 57 ++++++++--- .../chart/line_chart/line_chart_painter.dart | 22 +++-- repo_files/documentations/line_chart.md | 4 +- test/chart/data_pool.dart | 10 +- 6 files changed, 174 insertions(+), 30 deletions(-) create mode 100644 example/lib/line_chart/samples/line_chart_sample9.dart diff --git a/example/lib/line_chart/line_chart_page3.dart b/example/lib/line_chart/line_chart_page3.dart index d3c2aaacc..5f050bda6 100644 --- a/example/lib/line_chart/line_chart_page3.dart +++ b/example/lib/line_chart/line_chart_page3.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'samples/line_chart_sample6.dart'; +import 'samples/line_chart_sample9.dart'; class LineChartPage3 extends StatelessWidget { @override @@ -20,6 +21,17 @@ class LineChartPage3 extends StatelessWidget { height: 52, ), LineChartSample6(), + const SizedBox( + height: 52, + ), + const Text( + 'LineChart (positive and negative values)', + style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.black), + ), + const SizedBox( + height: 52, + ), + LineChartSample9(), ], ), ), diff --git a/example/lib/line_chart/samples/line_chart_sample9.dart b/example/lib/line_chart/samples/line_chart_sample9.dart new file mode 100644 index 000000000..e7c6de273 --- /dev/null +++ b/example/lib/line_chart/samples/line_chart_sample9.dart @@ -0,0 +1,99 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'dart:math'; + +// ignore: must_be_immutable +class LineChartSample9 extends StatelessWidget { + final spots = List.generate(101, (i) => (i - 50) / 10) + .map((x) => FlSpot(x, sin(x))) + .toList(); + + LineChartSample9() {} + + @override + Widget build(BuildContext context) { + return Container( + child: Padding( + padding: const EdgeInsets.only(right: 22.0, bottom: 20), + child: SizedBox( + width: 400, + height: 400, + child: LineChart( + LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + maxContentWidth: 100, + tooltipBgColor: Colors.orange, + getTooltipItems: (touchedSpots) { + return touchedSpots.map((LineBarSpot touchedSpot) { + final textStyle = TextStyle( + color: touchedSpot.bar.colors[0], + fontWeight: FontWeight.bold, + fontSize: 14, + ); + return LineTooltipItem( + '${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}', + textStyle); + }).toList(); + }), + handleBuiltInTouches: true, + getTouchLineStart: (data, index) => 0, + ), + lineBarsData: [ + LineChartBarData( + colors: [ + Colors.black, + ], + spots: spots, + isCurved: true, + isStrokeCapRound: true, + barWidth: 3, + belowBarData: BarAreaData( + show: false, + ), + dotData: FlDotData(show: false), + ), + ], + minY: -1.5, + maxY: 1.5, + titlesData: FlTitlesData( + leftTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.blueGrey, + fontWeight: FontWeight.bold, + fontSize: 18), + margin: 16, + ), + rightTitles: SideTitles(showTitles: false), + bottomTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.blueGrey, + fontWeight: FontWeight.bold, + fontSize: 18), + margin: 16, + ), + topTitles: SideTitles(showTitles: false), + ), + gridData: FlGridData( + show: true, + drawHorizontalLine: true, + drawVerticalLine: true, + horizontalInterval: 1.5, + verticalInterval: 5, + checkToShowHorizontalLine: (value) { + return value.toInt() == 0; + }, + checkToShowVerticalLine: (value) { + return value.toInt() == 0; + }, + ), + borderData: FlBorderData(show: false), + ), + ), + ), + ), + ); + } +} diff --git a/lib/src/chart/line_chart/line_chart_data.dart b/lib/src/chart/line_chart/line_chart_data.dart index 0998820bb..51985eba9 100644 --- a/lib/src/chart/line_chart/line_chart_data.dart +++ b/lib/src/chart/line_chart/line_chart_data.dart @@ -781,10 +781,10 @@ class FlDotData with EquatableMixin { /// This class contains the interface that all DotPainters should conform to. abstract class FlDotPainter with EquatableMixin { - /// This method should be overriden to draw the dot shape. + /// This method should be overridden to draw the dot shape. void draw(Canvas canvas, FlSpot spot, Offset offsetInCanvas); - /// This method should be overriden to return the size of the shape. + /// This method should be overridden to return the size of the shape. Size getSize(FlSpot spot); } @@ -1304,9 +1304,17 @@ class LineTouchData extends FlTouchData with EquatableMixin { /// [LineTouchResponse] shows a tooltip popup above the touched spot. final bool handleBuiltInTouches; - /// Sets the indicator line full height, from bottom to top of the chart, - /// and goes through the targeted spot. - final bool fullHeightTouchLine; + /// The starting point on y axis of the touch line. By default, line starts on the bottom of + /// the chart. + final GetTouchLineY getTouchLineStart; + + /// The end point on y axis of the touch line. By default, line ends at the touched point. + /// Though the line's length will be reduce to avoid overlap with the dot if + /// [touchLineEndAtDot] is true. + final GetTouchLineY getTouchLineEnd; + + /// Sets to avoid the touch line to overlap with the dot. Default is true. + final bool touchLineEndAtDot; /// Informs the touchResponses final Function(LineTouchResponse)? touchCallback; @@ -1316,10 +1324,8 @@ class LineTouchData extends FlTouchData with EquatableMixin { /// touch occurs (or you can show it manually using, [LineChartData.showingTooltipIndicators]) /// and also it shows an indicator (contains a thicker line and larger dot on the targeted spot), /// You can define how this indicator looks like through [getTouchedSpotIndicator] callback, - /// You can customize this tooltip using [touchTooltipData], indicator lines starts from bottom - /// of the chart to the targeted spot, you can change this behavior by [fullHeightTouchLine], - /// if [fullHeightTouchLine] sets true, the line goes from bottom to top of the chart, - /// and goes through the targeted spot. + /// You can customize this tooltip using [touchTooltipData], indicator lines starts from position + /// controlled by [getTouchLineStart] and ends at position controlled by [getTouchLineEnd]. /// If you need to have a distance threshold for handling touches, use [touchSpotThreshold]. /// /// You can listen to touch events using [touchCallback], @@ -1330,14 +1336,18 @@ class LineTouchData extends FlTouchData with EquatableMixin { LineTouchTooltipData? touchTooltipData, GetTouchedSpotIndicator? getTouchedSpotIndicator, double? touchSpotThreshold, - bool? fullHeightTouchLine, bool? handleBuiltInTouches, + GetTouchLineY? getTouchLineStart, + GetTouchLineY? getTouchLineEnd, + bool? touchLineEndAtDot, Function(LineTouchResponse)? touchCallback, }) : touchTooltipData = touchTooltipData ?? LineTouchTooltipData(), getTouchedSpotIndicator = getTouchedSpotIndicator ?? defaultTouchedIndicators, touchSpotThreshold = touchSpotThreshold ?? 10, - fullHeightTouchLine = fullHeightTouchLine ?? false, handleBuiltInTouches = handleBuiltInTouches ?? true, + getTouchLineStart = getTouchLineStart ?? defaultGetTouchLineStart, + getTouchLineEnd = getTouchLineEnd ?? defaultGetTouchLineEnd, + touchLineEndAtDot = touchLineEndAtDot ?? true, touchCallback = touchCallback, super(enabled ?? true); @@ -1348,7 +1358,9 @@ class LineTouchData extends FlTouchData with EquatableMixin { LineTouchTooltipData? touchTooltipData, GetTouchedSpotIndicator? getTouchedSpotIndicator, double? touchSpotThreshold, - bool? fullHeightTouchLine, + GetTouchLineY? getTouchLineStart, + GetTouchLineY? getTouchLineEnd, + bool? touchLineEndAtDot, bool? handleBuiltInTouches, Function(LineTouchResponse)? touchCallback, }) { @@ -1357,7 +1369,9 @@ class LineTouchData extends FlTouchData with EquatableMixin { touchTooltipData: touchTooltipData ?? this.touchTooltipData, getTouchedSpotIndicator: getTouchedSpotIndicator ?? this.getTouchedSpotIndicator, touchSpotThreshold: touchSpotThreshold ?? this.touchSpotThreshold, - fullHeightTouchLine: fullHeightTouchLine ?? this.fullHeightTouchLine, + getTouchLineStart: getTouchLineStart ?? this.getTouchLineStart, + getTouchLineEnd: getTouchLineEnd ?? this.getTouchLineEnd, + touchLineEndAtDot: touchLineEndAtDot ?? this.touchLineEndAtDot, handleBuiltInTouches: handleBuiltInTouches ?? this.handleBuiltInTouches, touchCallback: touchCallback ?? this.touchCallback, ); @@ -1370,7 +1384,9 @@ class LineTouchData extends FlTouchData with EquatableMixin { getTouchedSpotIndicator, touchSpotThreshold, handleBuiltInTouches, - fullHeightTouchLine, + getTouchLineStart, + getTouchLineEnd, + touchLineEndAtDot, touchCallback, enabled, ]; @@ -1385,6 +1401,9 @@ class LineTouchData extends FlTouchData with EquatableMixin { typedef GetTouchedSpotIndicator = List Function( LineChartBarData barData, List spotIndexes); +/// Used for determine the touch indicator line's starting/end point. +typedef GetTouchLineY = double Function(LineChartBarData barData, int spotIndex); + /// Default presentation of touched indicators. List defaultTouchedIndicators( LineChartBarData barData, List indicators) { @@ -1410,6 +1429,16 @@ List defaultTouchedIndicators( }).toList(); } +/// By default line starts from the bottom of the chart. +double defaultGetTouchLineStart(LineChartBarData barData, int spotIndex) { + return -double.infinity; +} + +/// By default line ends at the touched point. +double defaultGetTouchLineEnd(LineChartBarData barData, int spotIndex) { + return barData.spots[spotIndex].y; +} + /// Holds representation data for showing tooltip popup on top of spots. class LineTouchTooltipData with EquatableMixin { /// The tooltip background color. diff --git a/lib/src/chart/line_chart/line_chart_painter.dart b/lib/src/chart/line_chart/line_chart_painter.dart index c5175fee0..ff525097d 100644 --- a/lib/src/chart/line_chart/line_chart_painter.dart +++ b/lib/src/chart/line_chart/line_chart_painter.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:ui' as ui; import 'dart:ui'; @@ -297,19 +298,26 @@ class LineChartPainter extends AxisChartPainter } /// For drawing the indicator line - final bottom = Offset(touchedSpot.dx, getTopOffsetDrawSize() + chartViewSize.height); - final top = Offset(getPixelX(spot.x, chartViewSize), getTopOffsetDrawSize()); - - /// Draw to top or to the touchedSpot - final lineEnd = - data.lineTouchData.fullHeightTouchLine ? top : touchedSpot + Offset(0, dotHeight / 2); + final lineStartY = + min(data.maxY, max(data.minY, data.lineTouchData.getTouchLineStart(barData, index))); + final lineEndY = + min(data.maxY, max(data.minY, data.lineTouchData.getTouchLineEnd(barData, index))); + final lineStart = Offset(touchedSpot.dx, getPixelY(lineStartY, chartViewSize)); + var lineEnd = Offset(touchedSpot.dx, getPixelY(lineEndY, chartViewSize)); + if (data.lineTouchData.touchLineEndAtDot) { + if (lineStart.dy < lineEnd.dy) { + lineEnd -= Offset(0, dotHeight / 2); + } else { + lineEnd += Offset(0, dotHeight / 2); + } + } _touchLinePaint.color = indicatorData.indicatorBelowLine.color; _touchLinePaint.strokeWidth = indicatorData.indicatorBelowLine.strokeWidth; _touchLinePaint.transparentIfWidthIsZero(); canvasWrapper.drawDashedLine( - bottom, lineEnd, _touchLinePaint, indicatorData.indicatorBelowLine.dashArray); + lineStart, lineEnd, _touchLinePaint, indicatorData.indicatorBelowLine.dashArray); /// Draw the indicator dot if (showingDots) { diff --git a/repo_files/documentations/line_chart.md b/repo_files/documentations/line_chart.md index 4145d7988..1badced42 100644 --- a/repo_files/documentations/line_chart.md +++ b/repo_files/documentations/line_chart.md @@ -164,7 +164,9 @@ LineChart( |getTouchedSpotIndicator| a callback that retrieves list of [TouchedSpotIndicatorData](#TouchedSpotIndicatorData) by the given list of [LineBarSpot](#LineBarSpot) for showing the indicators on touched spots|defaultTouchedIndicators| |touchSpotThreshold|the threshold of the touch accuracy|10| |handleBuiltInTouches| set this true if you want the built in touch handling (show a tooltip bubble and an indicator on touched spots) | true| -|fullHeightTouchLine| set `true` to show the line in full height mode | false| +|getTouchLineStart| controls where the line starts, default is bottom of the chart| defaultGetTouchLineStart| +|getTouchLineEnd| controls where the line ends, default is the touch point| defaultGetTouchLineEnd| +|touchLineEndAtDot| whether to avoid the touch line to overlap with the dot| true| |touchCallback| listen to this callback to retrieve touch events, it gives you a [LineTouchResponse](#LineTouchResponse)| null| diff --git a/test/chart/data_pool.dart b/test/chart/data_pool.dart index defdf9a37..559f967ac 100644 --- a/test/chart/data_pool.dart +++ b/test/chart/data_pool.dart @@ -988,7 +988,6 @@ final LineTouchData lineTouchData1 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData1Clone = LineTouchData( enabled: true, @@ -997,7 +996,6 @@ final LineTouchData lineTouchData1Clone = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData2 = LineTouchData( @@ -1007,7 +1005,6 @@ final LineTouchData lineTouchData2 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData3 = LineTouchData( enabled: true, @@ -1016,7 +1013,6 @@ final LineTouchData lineTouchData3 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData4 = LineTouchData( enabled: true, @@ -1025,7 +1021,6 @@ final LineTouchData lineTouchData4 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: null, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData5 = LineTouchData( enabled: true, @@ -1034,7 +1029,6 @@ final LineTouchData lineTouchData5 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12.001, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData6 = LineTouchData( enabled: true, @@ -1043,7 +1037,6 @@ final LineTouchData lineTouchData6 = LineTouchData( handleBuiltInTouches: true, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: false, ); final LineTouchData lineTouchData7 = LineTouchData( enabled: true, @@ -1052,7 +1045,8 @@ final LineTouchData lineTouchData7 = LineTouchData( handleBuiltInTouches: false, touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, - fullHeightTouchLine: true, + getTouchLineEnd: (barData, index) => double.infinity, + touchLineEndAtDot: false, ); final String Function(HorizontalLine) horizontalLabelResolver = (horizontalLine) => 'test'; From 6f4c6fb934f9634bdcabf28affef3b4ed39e7368 Mon Sep 17 00:00:00 2001 From: terryl1900 Date: Mon, 15 Mar 2021 16:09:03 -0700 Subject: [PATCH 2/4] Fix example. --- .../samples/line_chart_sample8.dart | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/example/lib/line_chart/samples/line_chart_sample8.dart b/example/lib/line_chart/samples/line_chart_sample8.dart index 96d192301..a97227e09 100644 --- a/example/lib/line_chart/samples/line_chart_sample8.dart +++ b/example/lib/line_chart/samples/line_chart_sample8.dart @@ -22,7 +22,8 @@ class _LineChartSample8State extends State { Future loadImage(String asset) async { final ByteData data = await rootBundle.load(asset); - final ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List()); + final ui.Codec codec = + await ui.instantiateImageCodec(data.buffer.asUint8List()); final ui.FrameInfo fi = await codec.getNextFrame(); return fi.image; } @@ -50,7 +51,8 @@ class _LineChartSample8State extends State { aspectRatio: 1.70, child: Container( child: Padding( - padding: const EdgeInsets.only(right: 18.0, left: 12.0, top: 24, bottom: 12), + padding: const EdgeInsets.only( + right: 18.0, left: 12.0, top: 24, bottom: 12), child: LineChart( mainData(imageSnapshot.data), ), @@ -128,16 +130,21 @@ class _LineChartSample8State extends State { ], ), gridData: FlGridData( - show: true, drawVerticalLine: false, drawHorizontalLine: false, verticalInterval: 1), + show: true, + drawVerticalLine: false, + drawHorizontalLine: false, + verticalInterval: 1), titlesData: FlTitlesData( show: true, bottomTitles: SideTitles( showTitles: true, reservedSize: 22, - getTextStyles: (value) => const TextStyle(color: Colors.black87, fontSize: 10), + getTextStyles: (value) => + const TextStyle(color: Colors.black87, fontSize: 10), interval: 4, margin: 8, - checkToShowTitle: (minValue, maxValue, sideTitles, appliedInterval, value) => true, + checkToShowTitle: + (minValue, maxValue, sideTitles, appliedInterval, value) => true, ), leftTitles: SideTitles( interval: 2, @@ -151,8 +158,10 @@ class _LineChartSample8State extends State { ), ), lineTouchData: LineTouchData( - fullHeightTouchLine: true, - getTouchedSpotIndicator: (LineChartBarData barData, List spotIndexes) { + getTouchLineEnd: (data, index) => double.infinity, + touchLineEndAtDot: false, + getTouchedSpotIndicator: + (LineChartBarData barData, List spotIndexes) { return spotIndexes.map((spotIndex) { return TouchedSpotIndicatorData( FlLine(color: Colors.orange, strokeWidth: 3), @@ -166,8 +175,9 @@ class _LineChartSample8State extends State { tooltipBgColor: Colors.blueAccent, ), ), - borderData: - FlBorderData(show: true, border: Border.all(color: const Color(0xffecf1fe), width: 1)), + borderData: FlBorderData( + show: true, + border: Border.all(color: const Color(0xffecf1fe), width: 1)), minX: 0, maxX: 11, minY: 0, @@ -196,7 +206,8 @@ class _LineChartSample8State extends State { ), belowBarData: BarAreaData( show: false, - colors: gradientColors.map((color) => color.withOpacity(0.5)).toList(), + colors: + gradientColors.map((color) => color.withOpacity(0.5)).toList(), ), ), ], From 0d4c584056e21febf86d043824a6b360677c1039 Mon Sep 17 00:00:00 2001 From: terryl1900 Date: Mon, 15 Mar 2021 17:23:10 -0700 Subject: [PATCH 3/4] Run format. --- .../samples/line_chart_sample8.dart | 28 ++++++------------- .../samples/line_chart_sample9.dart | 15 +++------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/example/lib/line_chart/samples/line_chart_sample8.dart b/example/lib/line_chart/samples/line_chart_sample8.dart index a97227e09..2906f2928 100644 --- a/example/lib/line_chart/samples/line_chart_sample8.dart +++ b/example/lib/line_chart/samples/line_chart_sample8.dart @@ -22,8 +22,7 @@ class _LineChartSample8State extends State { Future loadImage(String asset) async { final ByteData data = await rootBundle.load(asset); - final ui.Codec codec = - await ui.instantiateImageCodec(data.buffer.asUint8List()); + final ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List()); final ui.FrameInfo fi = await codec.getNextFrame(); return fi.image; } @@ -51,8 +50,7 @@ class _LineChartSample8State extends State { aspectRatio: 1.70, child: Container( child: Padding( - padding: const EdgeInsets.only( - right: 18.0, left: 12.0, top: 24, bottom: 12), + padding: const EdgeInsets.only(right: 18.0, left: 12.0, top: 24, bottom: 12), child: LineChart( mainData(imageSnapshot.data), ), @@ -130,21 +128,16 @@ class _LineChartSample8State extends State { ], ), gridData: FlGridData( - show: true, - drawVerticalLine: false, - drawHorizontalLine: false, - verticalInterval: 1), + show: true, drawVerticalLine: false, drawHorizontalLine: false, verticalInterval: 1), titlesData: FlTitlesData( show: true, bottomTitles: SideTitles( showTitles: true, reservedSize: 22, - getTextStyles: (value) => - const TextStyle(color: Colors.black87, fontSize: 10), + getTextStyles: (value) => const TextStyle(color: Colors.black87, fontSize: 10), interval: 4, margin: 8, - checkToShowTitle: - (minValue, maxValue, sideTitles, appliedInterval, value) => true, + checkToShowTitle: (minValue, maxValue, sideTitles, appliedInterval, value) => true, ), leftTitles: SideTitles( interval: 2, @@ -160,8 +153,7 @@ class _LineChartSample8State extends State { lineTouchData: LineTouchData( getTouchLineEnd: (data, index) => double.infinity, touchLineEndAtDot: false, - getTouchedSpotIndicator: - (LineChartBarData barData, List spotIndexes) { + getTouchedSpotIndicator: (LineChartBarData barData, List spotIndexes) { return spotIndexes.map((spotIndex) { return TouchedSpotIndicatorData( FlLine(color: Colors.orange, strokeWidth: 3), @@ -175,9 +167,8 @@ class _LineChartSample8State extends State { tooltipBgColor: Colors.blueAccent, ), ), - borderData: FlBorderData( - show: true, - border: Border.all(color: const Color(0xffecf1fe), width: 1)), + borderData: + FlBorderData(show: true, border: Border.all(color: const Color(0xffecf1fe), width: 1)), minX: 0, maxX: 11, minY: 0, @@ -206,8 +197,7 @@ class _LineChartSample8State extends State { ), belowBarData: BarAreaData( show: false, - colors: - gradientColors.map((color) => color.withOpacity(0.5)).toList(), + colors: gradientColors.map((color) => color.withOpacity(0.5)).toList(), ), ), ], diff --git a/example/lib/line_chart/samples/line_chart_sample9.dart b/example/lib/line_chart/samples/line_chart_sample9.dart index e7c6de273..96e2e38b8 100644 --- a/example/lib/line_chart/samples/line_chart_sample9.dart +++ b/example/lib/line_chart/samples/line_chart_sample9.dart @@ -4,9 +4,7 @@ import 'dart:math'; // ignore: must_be_immutable class LineChartSample9 extends StatelessWidget { - final spots = List.generate(101, (i) => (i - 50) / 10) - .map((x) => FlSpot(x, sin(x))) - .toList(); + final spots = List.generate(101, (i) => (i - 50) / 10).map((x) => FlSpot(x, sin(x))).toList(); LineChartSample9() {} @@ -32,8 +30,7 @@ class LineChartSample9 extends StatelessWidget { fontSize: 14, ); return LineTooltipItem( - '${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}', - textStyle); + '${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}', textStyle); }).toList(); }), handleBuiltInTouches: true, @@ -60,18 +57,14 @@ class LineChartSample9 extends StatelessWidget { leftTitles: SideTitles( showTitles: true, getTextStyles: (value) => const TextStyle( - color: Colors.blueGrey, - fontWeight: FontWeight.bold, - fontSize: 18), + color: Colors.blueGrey, fontWeight: FontWeight.bold, fontSize: 18), margin: 16, ), rightTitles: SideTitles(showTitles: false), bottomTitles: SideTitles( showTitles: true, getTextStyles: (value) => const TextStyle( - color: Colors.blueGrey, - fontWeight: FontWeight.bold, - fontSize: 18), + color: Colors.blueGrey, fontWeight: FontWeight.bold, fontSize: 18), margin: 16, ), topTitles: SideTitles(showTitles: false), From d9c7af8be0e83e2c12660a6b0a27892e210e53f7 Mon Sep 17 00:00:00 2001 From: terryl1900 Date: Mon, 22 Mar 2021 13:50:42 -0700 Subject: [PATCH 4/4] Remove touchLineEndAtDot. --- .../lib/line_chart/samples/line_chart_sample8.dart | 1 - lib/src/chart/line_chart/line_chart_data.dart | 11 +---------- lib/src/chart/line_chart/line_chart_painter.dart | 10 +++++++--- repo_files/documentations/line_chart.md | 1 - test/chart/data_pool.dart | 1 - 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/example/lib/line_chart/samples/line_chart_sample8.dart b/example/lib/line_chart/samples/line_chart_sample8.dart index 2906f2928..2a24036a5 100644 --- a/example/lib/line_chart/samples/line_chart_sample8.dart +++ b/example/lib/line_chart/samples/line_chart_sample8.dart @@ -152,7 +152,6 @@ class _LineChartSample8State extends State { ), lineTouchData: LineTouchData( getTouchLineEnd: (data, index) => double.infinity, - touchLineEndAtDot: false, getTouchedSpotIndicator: (LineChartBarData barData, List spotIndexes) { return spotIndexes.map((spotIndex) { return TouchedSpotIndicatorData( diff --git a/lib/src/chart/line_chart/line_chart_data.dart b/lib/src/chart/line_chart/line_chart_data.dart index fbdfca1f7..e71858940 100644 --- a/lib/src/chart/line_chart/line_chart_data.dart +++ b/lib/src/chart/line_chart/line_chart_data.dart @@ -1308,13 +1308,9 @@ class LineTouchData extends FlTouchData with EquatableMixin { final GetTouchLineY getTouchLineStart; /// The end point on y axis of the touch line. By default, line ends at the touched point. - /// Though the line's length will be reduce to avoid overlap with the dot if - /// [touchLineEndAtDot] is true. + /// If line end is overlap with the dot, it will be automatically adjusted to the edge of the dot. final GetTouchLineY getTouchLineEnd; - /// Sets to avoid the touch line to overlap with the dot. Default is true. - final bool touchLineEndAtDot; - /// Informs the touchResponses final LineTouchCallback? touchCallback; @@ -1338,7 +1334,6 @@ class LineTouchData extends FlTouchData with EquatableMixin { bool? handleBuiltInTouches, GetTouchLineY? getTouchLineStart, GetTouchLineY? getTouchLineEnd, - bool? touchLineEndAtDot, LineTouchCallback? touchCallback, }) : touchTooltipData = touchTooltipData ?? LineTouchTooltipData(), getTouchedSpotIndicator = getTouchedSpotIndicator ?? defaultTouchedIndicators, @@ -1346,7 +1341,6 @@ class LineTouchData extends FlTouchData with EquatableMixin { handleBuiltInTouches = handleBuiltInTouches ?? true, getTouchLineStart = getTouchLineStart ?? defaultGetTouchLineStart, getTouchLineEnd = getTouchLineEnd ?? defaultGetTouchLineEnd, - touchLineEndAtDot = touchLineEndAtDot ?? true, touchCallback = touchCallback, super(enabled ?? true); @@ -1359,7 +1353,6 @@ class LineTouchData extends FlTouchData with EquatableMixin { double? touchSpotThreshold, GetTouchLineY? getTouchLineStart, GetTouchLineY? getTouchLineEnd, - bool? touchLineEndAtDot, bool? handleBuiltInTouches, Function(LineTouchResponse)? touchCallback, }) { @@ -1370,7 +1363,6 @@ class LineTouchData extends FlTouchData with EquatableMixin { touchSpotThreshold: touchSpotThreshold ?? this.touchSpotThreshold, getTouchLineStart: getTouchLineStart ?? this.getTouchLineStart, getTouchLineEnd: getTouchLineEnd ?? this.getTouchLineEnd, - touchLineEndAtDot: touchLineEndAtDot ?? this.touchLineEndAtDot, handleBuiltInTouches: handleBuiltInTouches ?? this.handleBuiltInTouches, touchCallback: touchCallback ?? this.touchCallback, ); @@ -1385,7 +1377,6 @@ class LineTouchData extends FlTouchData with EquatableMixin { handleBuiltInTouches, getTouchLineStart, getTouchLineEnd, - touchLineEndAtDot, touchCallback, enabled, ]; diff --git a/lib/src/chart/line_chart/line_chart_painter.dart b/lib/src/chart/line_chart/line_chart_painter.dart index 600d908c0..a5fa8d8e9 100644 --- a/lib/src/chart/line_chart/line_chart_painter.dart +++ b/lib/src/chart/line_chart/line_chart_painter.dart @@ -320,11 +320,15 @@ class LineChartPainter extends AxisChartPainter { min(data.maxY, max(data.minY, data.lineTouchData.getTouchLineEnd(barData, index))); final lineStart = Offset(touchedSpot.dx, getPixelY(lineStartY, chartViewSize, holder)); var lineEnd = Offset(touchedSpot.dx, getPixelY(lineEndY, chartViewSize, holder)); - if (data.lineTouchData.touchLineEndAtDot) { + + /// If line end is inside the dot, adjust it so that it doesn't overlap with the dot. + final dotMinY = touchedSpot.dy - dotHeight / 2; + final dotMaxY = touchedSpot.dy + dotHeight / 2; + if (lineEnd.dy > dotMinY && lineEnd.dy < dotMaxY) { if (lineStart.dy < lineEnd.dy) { - lineEnd -= Offset(0, dotHeight / 2); + lineEnd -= Offset(0, lineEnd.dy - dotMinY); } else { - lineEnd += Offset(0, dotHeight / 2); + lineEnd += Offset(0, dotMaxY - lineEnd.dy); } } diff --git a/repo_files/documentations/line_chart.md b/repo_files/documentations/line_chart.md index 9afe55671..5924e6e1d 100644 --- a/repo_files/documentations/line_chart.md +++ b/repo_files/documentations/line_chart.md @@ -171,7 +171,6 @@ When you change the chart's state, it animates to the new state internally (usin |handleBuiltInTouches| set this true if you want the built in touch handling (show a tooltip bubble and an indicator on touched spots) | true| |getTouchLineStart| controls where the line starts, default is bottom of the chart| defaultGetTouchLineStart| |getTouchLineEnd| controls where the line ends, default is the touch point| defaultGetTouchLineEnd| -|touchLineEndAtDot| whether to avoid the touch line to overlap with the dot| true| |touchCallback| listen to this callback to retrieve touch events, it gives you a [LineTouchResponse](#LineTouchResponse)| null| diff --git a/test/chart/data_pool.dart b/test/chart/data_pool.dart index 7bc4ee4af..b9c5a5f39 100644 --- a/test/chart/data_pool.dart +++ b/test/chart/data_pool.dart @@ -1048,7 +1048,6 @@ final LineTouchData lineTouchData7 = LineTouchData( touchSpotThreshold: 12, touchTooltipData: lineTouchTooltipData1, getTouchLineEnd: (barData, index) => double.infinity, - touchLineEndAtDot: false, ); final String Function(HorizontalLine) horizontalLabelResolver = (horizontalLine) => 'test';