Skip to content

Commit

Permalink
Merge pull request imaNNeo#602 from terryl1900/tooltip-position
Browse files Browse the repository at this point in the history
Control bar chart tooltip direction.
  • Loading branch information
imaNNeo authored Mar 16, 2021
2 parents 15050f8 + c41042d commit 5c66afc
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 36 deletions.
2 changes: 1 addition & 1 deletion example/lib/bar_chart/samples/bar_chart_sample3.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BarChartSample3State extends State<BarChartSample3> {
touchTooltipData: BarTouchTooltipData(
tooltipBgColor: Colors.transparent,
tooltipPadding: const EdgeInsets.all(0),
tooltipBottomMargin: 8,
tooltipMargin: 8,
getTooltipItem: (
BarChartGroupData group,
int groupIndex,
Expand Down
27 changes: 22 additions & 5 deletions lib/src/chart/bar_chart/bar_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,18 @@ class BarTouchData extends FlTouchData with EquatableMixin {
];
}

/// Controls showing tooltip on top or bottom.
enum TooltipDirection {
/// Tooltip shows on top if value is positive, on bottom if value is negative.
auto,

/// Tooltip always shows on top.
top,

/// Tooltip always shows on bottom.
bottom,
}

/// Holds representation data for showing tooltip popup on top of rods.
class BarTouchTooltipData with EquatableMixin {
/// The tooltip background color.
Expand All @@ -614,7 +626,7 @@ class BarTouchTooltipData with EquatableMixin {
final EdgeInsets tooltipPadding;

/// Applies a bottom margin for showing tooltip on top of rods.
final double tooltipBottomMargin;
final double tooltipMargin;

/// Restricts the tooltip's width.
final double maxContentWidth;
Expand All @@ -628,13 +640,16 @@ class BarTouchTooltipData with EquatableMixin {
/// Forces the tooltip to shift vertically inside the chart, if overflow happens.
final bool fitInsideVertically;

/// Controls showing tooltip on top or bottom, default is auto.
final TooltipDirection direction;

/// if [BarTouchData.handleBuiltInTouches] is true,
/// [BarChart] shows a tooltip popup on top of rods automatically when touch happens,
/// otherwise you can show it manually using [BarChartGroupData.showingTooltipIndicators].
/// Tooltip shows on top of rods, with [tooltipBgColor] as a background color,
/// and you can set corner radius using [tooltipRoundedRadius].
/// If you want to have a padding inside the tooltip, fill [tooltipPadding],
/// or If you want to have a bottom margin, set [tooltipBottomMargin].
/// or If you want to have a bottom margin, set [tooltipMargin].
/// Content of the tooltip will provide using [getTooltipItem] callback, you can override it
/// and pass your custom data to show in the tooltip.
/// You can restrict the tooltip's width using [maxContentWidth].
Expand All @@ -645,19 +660,21 @@ class BarTouchTooltipData with EquatableMixin {
Color? tooltipBgColor,
double? tooltipRoundedRadius,
EdgeInsets? tooltipPadding,
double? tooltipBottomMargin,
double? tooltipMargin,
double? maxContentWidth,
GetBarTooltipItem? getTooltipItem,
bool? fitInsideHorizontally,
bool? fitInsideVertically,
TooltipDirection? direction,
}) : tooltipBgColor = tooltipBgColor ?? Colors.white,
tooltipRoundedRadius = tooltipRoundedRadius ?? 4,
tooltipPadding = tooltipPadding ?? const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
tooltipBottomMargin = tooltipBottomMargin ?? 16,
tooltipMargin = tooltipMargin ?? 16,
maxContentWidth = maxContentWidth ?? 120,
getTooltipItem = getTooltipItem ?? defaultBarTooltipItem,
fitInsideHorizontally = fitInsideHorizontally ?? false,
fitInsideVertically = fitInsideVertically ?? false,
direction = direction ?? TooltipDirection.auto,
super();

/// Used for equality check, see [EquatableMixin].
Expand All @@ -666,7 +683,7 @@ class BarTouchTooltipData with EquatableMixin {
tooltipBgColor,
tooltipRoundedRadius,
tooltipPadding,
tooltipBottomMargin,
tooltipMargin,
maxContentWidth,
getTooltipItem,
fitInsideHorizontally,
Expand Down
13 changes: 8 additions & 5 deletions lib/src/chart/bar_chart/bar_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -518,14 +518,17 @@ class BarChartPainter extends AxisChartPainter<BarChartData> with TouchHandler<B
getPixelY(showOnRodData.y, chartUsableSize),
);

final isPositive = showOnRodData.y > 0;

final tooltipWidth = textWidth + tooltipData.tooltipPadding.horizontal;
final tooltipHeight = textHeight + tooltipData.tooltipPadding.vertical;

final tooltipTop = isPositive
? barOffset.dy - tooltipHeight - tooltipData.tooltipBottomMargin
: barOffset.dy + tooltipData.tooltipBottomMargin;
final zeroY = getPixelY(0, chartUsableSize);
final barTopY = min(zeroY, barOffset.dy);
final barBottomY = max(zeroY, barOffset.dy);
final drawTooltipOnTop = tooltipData.direction == TooltipDirection.top ||
(tooltipData.direction == TooltipDirection.auto && showOnRodData.y > 0);
final tooltipTop = drawTooltipOnTop
? barTopY - tooltipHeight - tooltipData.tooltipMargin
: barBottomY + tooltipData.tooltipMargin;

/// draw the background rect with rounded radius
// ignore: omit_local_variable_types
Expand Down
10 changes: 5 additions & 5 deletions lib/src/chart/line_chart/line_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,7 @@ class LineTouchTooltipData with EquatableMixin {
final EdgeInsets tooltipPadding;

/// Applies a bottom margin for showing tooltip on top of rods.
final double tooltipBottomMargin;
final double tooltipMargin;

/// Restricts the tooltip's width.
final double maxContentWidth;
Expand All @@ -1445,7 +1445,7 @@ class LineTouchTooltipData with EquatableMixin {
/// Tooltip shows on top of spots, with [tooltipBgColor] as a background color,
/// and you can set corner radius using [tooltipRoundedRadius].
/// If you want to have a padding inside the tooltip, fill [tooltipPadding],
/// or If you want to have a bottom margin, set [tooltipBottomMargin].
/// or If you want to have a bottom margin, set [tooltipMargin].
/// Content of the tooltip will provide using [getTooltipItems] callback, you can override it
/// and pass your custom data to show in the tooltip.
/// You can restrict the tooltip's width using [maxContentWidth].
Expand All @@ -1456,7 +1456,7 @@ class LineTouchTooltipData with EquatableMixin {
Color? tooltipBgColor,
double? tooltipRoundedRadius,
EdgeInsets? tooltipPadding,
double? tooltipBottomMargin,
double? tooltipMargin,
double? maxContentWidth,
GetLineTooltipItems? getTooltipItems,
bool? fitInsideHorizontally,
Expand All @@ -1465,7 +1465,7 @@ class LineTouchTooltipData with EquatableMixin {
}) : tooltipBgColor = tooltipBgColor ?? Colors.white,
tooltipRoundedRadius = tooltipRoundedRadius ?? 4,
tooltipPadding = tooltipPadding ?? const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
tooltipBottomMargin = tooltipBottomMargin ?? 16,
tooltipMargin = tooltipMargin ?? 16,
maxContentWidth = maxContentWidth ?? 120,
getTooltipItems = getTooltipItems ?? defaultLineTooltipItem,
fitInsideHorizontally = fitInsideHorizontally ?? false,
Expand All @@ -1479,7 +1479,7 @@ class LineTouchTooltipData with EquatableMixin {
tooltipBgColor,
tooltipRoundedRadius,
tooltipPadding,
tooltipBottomMargin,
tooltipMargin,
maxContentWidth,
getTooltipItems,
fitInsideHorizontally,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/chart/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1158,9 +1158,9 @@ class LineChartPainter extends AxisChartPainter<LineChartData>

double tooltipTopPosition;
if (tooltipData.showOnTopOfTheChartBoxArea) {
tooltipTopPosition = 0 - tooltipHeight - tooltipData.tooltipBottomMargin;
tooltipTopPosition = 0 - tooltipHeight - tooltipData.tooltipMargin;
} else {
tooltipTopPosition = mostTopOffset.dy - tooltipHeight - tooltipData.tooltipBottomMargin;
tooltipTopPosition = mostTopOffset.dy - tooltipHeight - tooltipData.tooltipMargin;
}

/// draw the background rect with rounded radius
Expand Down
3 changes: 2 additions & 1 deletion repo_files/documentations/bar_chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ enum values {`start`, `end`, `center`, `spaceEvenly`, `spaceAround`, `spaceBetwe
|tooltipBgColor|background color of the tooltip bubble|Colors.white|
|tooltipRoundedRadius|background corner radius of the tooltip bubble|4|
|tooltipPadding|padding of the tooltip|EdgeInsets.symmetric(horizontal: 16, vertical: 8)|
|tooltipBottomMargin|bottom margin of the tooltip (to the top of most top spot)|16|
|tooltipMargin|margin between the tooltip and the touched spot|16|
|maxContentWidth|maximum width of the tooltip (if a text row is wider than this, then the text breaks to a new line|120|
|getTooltipItems|a callback that retrieve [BarTooltipItem](#BarTooltipItem) by the given [BarChartGroupData](#BarChartGroupData), groupIndex, [BarChartRodData](#BarChartRodData) and rodIndex |defaultBarTooltipItem|
|fitInsideHorizontally| forces tooltip to horizontally shift inside the chart's bounding box| false|
|fitInsideVertically| forces tooltip to vertically shift inside the chart's bounding box| false|
|direction| Controls showing tooltip on top or bottom, default is auto.| auto|

### BarTooltipItem
|PropName|Description|default value|
Expand Down
2 changes: 1 addition & 1 deletion repo_files/documentations/line_chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ LineChart(
|tooltipBgColor|background color of the tooltip bubble|Colors.white|
|tooltipRoundedRadius|background corner radius of the tooltip bubble|4|
|tooltipPadding|padding of the tooltip|EdgeInsets.symmetric(horizontal: 16, vertical: 8)|
|tooltipBottomMargin|bottom margin of the tooltip (to the top of most top spot)|16|
|tooltipMargin|margin between the tooltip and the touched spot|16|
|maxContentWidth|maximum width of the tooltip (if a text row is wider than this, then the text breaks to a new line|120|
|getTooltipItems|a callback that retrieve list of [LineTooltipItem](#LineTooltipItem) by the given list of [LineBarSpot](#LineBarSpot) |defaultLineTooltipItem|
|fitInsideHorizontally| forces tooltip to horizontally shift inside the chart's bounding box| false|
Expand Down
32 changes: 16 additions & 16 deletions test/chart/data_pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ final LineTouchTooltipData lineTouchTooltipData1 = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 33,
tooltipMargin: 33,
);
final LineTouchTooltipData lineTouchTooltipData1Clone = LineTouchTooltipData(
tooltipPadding: const EdgeInsets.all(0.1),
Expand All @@ -931,7 +931,7 @@ final LineTouchTooltipData lineTouchTooltipData1Clone = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 33,
tooltipMargin: 33,
);

final LineTouchTooltipData lineTouchTooltipData2 = LineTouchTooltipData(
Expand All @@ -942,7 +942,7 @@ final LineTouchTooltipData lineTouchTooltipData2 = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 33,
tooltipMargin: 33,
);
final LineTouchTooltipData lineTouchTooltipData3 = LineTouchTooltipData(
tooltipPadding: const EdgeInsets.all(0.2),
Expand All @@ -952,7 +952,7 @@ final LineTouchTooltipData lineTouchTooltipData3 = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 33,
tooltipMargin: 33,
);
final LineTouchTooltipData lineTouchTooltipData4 = LineTouchTooltipData(
tooltipPadding: const EdgeInsets.all(0.1),
Expand All @@ -962,7 +962,7 @@ final LineTouchTooltipData lineTouchTooltipData4 = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 33,
tooltipMargin: 33,
);
final LineTouchTooltipData lineTouchTooltipData5 = LineTouchTooltipData(
tooltipPadding: const EdgeInsets.all(0.1),
Expand All @@ -972,7 +972,7 @@ final LineTouchTooltipData lineTouchTooltipData5 = LineTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: false,
tooltipRoundedRadius: 12,
tooltipBottomMargin: 34,
tooltipMargin: 34,
);

final Function(LineTouchResponse) lineTouchCallback = (response) {};
Expand Down Expand Up @@ -2580,7 +2580,7 @@ final BarTouchTooltipData barTouchTooltipData1 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData1Clone = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2590,7 +2590,7 @@ final BarTouchTooltipData barTouchTooltipData1Clone = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData2 = BarTouchTooltipData(
tooltipRoundedRadius: 13,
Expand All @@ -2600,7 +2600,7 @@ final BarTouchTooltipData barTouchTooltipData2 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData3 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2610,7 +2610,7 @@ final BarTouchTooltipData barTouchTooltipData3 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData4 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2620,7 +2620,7 @@ final BarTouchTooltipData barTouchTooltipData4 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData5 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2630,7 +2630,7 @@ final BarTouchTooltipData barTouchTooltipData5 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData6 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2640,7 +2640,7 @@ final BarTouchTooltipData barTouchTooltipData6 = BarTouchTooltipData(
tooltipBgColor: Colors.blue,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData7 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2650,7 +2650,7 @@ final BarTouchTooltipData barTouchTooltipData7 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: null,
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData8 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2660,7 +2660,7 @@ final BarTouchTooltipData barTouchTooltipData8 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: null,
tooltipBottomMargin: 12,
tooltipMargin: 12,
);
final BarTouchTooltipData barTouchTooltipData9 = BarTouchTooltipData(
tooltipRoundedRadius: 12,
Expand All @@ -2670,7 +2670,7 @@ final BarTouchTooltipData barTouchTooltipData9 = BarTouchTooltipData(
tooltipBgColor: Colors.green,
tooltipPadding: const EdgeInsets.all(23),
getTooltipItem: getTooltipItem,
tooltipBottomMargin: 333,
tooltipMargin: 333,
);

final Function(BarTouchResponse) barTouchCallback = (response) {};
Expand Down

0 comments on commit 5c66afc

Please sign in to comment.