Skip to content
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
8 changes: 6 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,19 @@ class MyApp extends StatelessWidget {
data: smallDataList,
chartType: ChartType.amount,
viewMode: ViewMode.weekly,
barColor: Colors.deepPurple,
chartStyle: ChartStyle(
barColor: Colors.deepPurple
),
),
sizedBox,
const Text('Monthly amount chart'),
TimeChart(
data: smallDataList,
chartType: ChartType.amount,
viewMode: ViewMode.monthly,
barColor: Colors.deepPurple,
chartStyle: ChartStyle(
barColor: Colors.deepPurple
)
),
],
),
Expand Down
47 changes: 13 additions & 34 deletions lib/src/chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:linked_scroll_controller/linked_scroll_controller.dart';
import 'package:touchable/touchable.dart';

import '../time_chart.dart';
import 'components/chart_style.dart';
import 'components/painter/amount_chart/amount_x_label_painter.dart';
import 'components/painter/amount_chart/amount_y_label_painter.dart';
import 'components/painter/time_chart/time_x_label_painter.dart';
Expand All @@ -26,36 +27,38 @@ import 'components/translations/translations.dart';
import 'components/utils/context_utils.dart';

class Chart extends StatefulWidget {
const Chart({
Chart({
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here

Suggested change
Chart({
const Chart({

Key? key,
required this.chartType,
required this.width,
required this.height,
required this.barColor,
required this.data,
required this.timeChartSizeAnimationDuration,
required this.tooltipDuration,
required this.tooltipBackgroundColor,
required this.tooltipStart,
required this.tooltipEnd,
required this.activeTooltip,
required this.viewMode,
required this.defaultPivotHour,
}) : super(key: key);
this.chartStyle,
}) : super(key: key) {
kLineColor3 = chartStyle?.verticalGridColor ?? kLineColor3;
kLineColor1 = chartStyle?.horizontalGridColor ?? kLineColor1;
kTextColor = chartStyle?.labelColor ?? kLineColor3;
}

final ChartType chartType;
final double width;
final double height;
final Color? barColor;
final List<DateTimeRange> data;
final Duration timeChartSizeAnimationDuration;
final Duration tooltipDuration;
final Color? tooltipBackgroundColor;
final String tooltipStart;
final String tooltipEnd;
final bool activeTooltip;
final ViewMode viewMode;
final int defaultPivotHour;
final ChartStyle? chartStyle;

@override
ChartState createState() => ChartState();
Expand Down Expand Up @@ -155,8 +158,7 @@ class ChartState extends State<Chart>
DateTime _getFirstItemDate({Duration addition = Duration.zero}) {
return widget.data.isEmpty
? DateTime.now()
: widget.data.first.end.dateWithoutTime().add(addition);
}
: widget.data.first.end.dateWithoutTime().add(addition); }

void _addScrollNotifier() {
WidgetsBinding.instance.addPostFrameCallback((_) {
Expand Down Expand Up @@ -253,15 +255,13 @@ class ChartState extends State<Chart>
final scrollPixels = position.maxScrollExtent - position.pixels;
final localLeft = rect.left + widgetOffset.dx - scrollPixels;
final tooltipTop = max(candidateTop, 0.0);

Direction direction = Direction.left;
double tooltipLeft = localLeft - tooltipSize.width - _tooltipPadding;
// 툴팁을 바의 오른쪽에 배치해야 하는 경우
if (tooltipLeft < widgetOffset.dx) {
direction = Direction.right;
tooltipLeft = localLeft + barWidth + _tooltipPadding;
}

return Positioned(
// 바 옆에 [tooltip]을 띄운다.
top: tooltipTop,
Expand All @@ -272,7 +272,7 @@ class ChartState extends State<Chart>
curve: Curves.fastOutSlowIn,
),
child: TooltipOverlay(
backgroundColor: widget.tooltipBackgroundColor,
backgroundColor: widget.chartStyle?.tooltipBackgroundColor,
chartType: chartType,
bottomHour: bottomHour,
timeRange: range,
Expand All @@ -285,19 +285,16 @@ class ChartState extends State<Chart>
),
);
}

/// 현재 존재하는 툴팁을 제거한다.
void _removeEntry() {
_tooltipHideTimer?.cancel();
_tooltipHideTimer = null;
_overlayEntry?.remove();
_overlayEntry = null;
}

void _cancelTimer() {
_pivotHourUpdatingTimer?.cancel();
}

double _getRightMargin(BuildContext context) {
final translations = Translations(context);
final TextPainter tp = TextPainter(
Expand All @@ -313,14 +310,11 @@ class ChartState extends State<Chart>
tp.layout();
return tp.width + kYLabelMargin;
}

void _handlePanDown(_) {
_scrollPhysics!.setPanDownPixels(_barController.position.pixels);
}

bool _handleScrollNotification(ScrollNotification notification) {
if (widget.chartType == ChartType.amount) return false;

if (notification is ScrollStartNotification) {
_cancelTimer();
} else if (notification is ScrollEndNotification) {
Expand All @@ -329,7 +323,6 @@ class ChartState extends State<Chart>
}
return true;
}

void _timerCallback() {
final beforeIsFirstDataMovedNextDay = isFirstDataMovedNextDay;
final beforeTopHour = topHour;
Expand All @@ -342,23 +335,17 @@ class ChartState extends State<Chart>
final scrollPositionDuration = Duration(
days: -blockIndex + (needsToAdaptScrollPosition ? 1 : 0),
);

processData(widget, _getFirstItemDate(addition: scrollPositionDuration));

if (topHour == beforeTopHour && bottomHour == beforeBottomHour) return;

if (beforeIsFirstDataMovedNextDay != isFirstDataMovedNextDay) {
// 하루가 추가 혹은 삭제되는 경우 x축 방향으로 발생하는 차이를 해결할 값이다.
final add = isFirstDataMovedNextDay ? _blockWidth! : -_blockWidth!;

_barController.jumpTo(_barController.position.pixels + add);
_scrollPhysics!.addPanDownPixels(add);
_scrollPhysics!.setDayCount(dayCount!);
}

_runHeightAnimation(beforeTopHour!, beforeBottomHour!);
}

double get heightWithoutLabel => widget.height - kXLabelHeight;

void _runHeightAnimation(int beforeTopHour, int beforeBottomHour) {
Expand All @@ -383,18 +370,14 @@ class ChartState extends State<Chart>
});
_sizeController.reverse(from: 1.0);
}

@override
Widget build(BuildContext context) {
final int viewModeLimitDay = widget.viewMode.dayCount;
final key = ValueKey((topHour ?? 0) + (bottomHour ?? 1) * 100);

final double outerHeight = kTimeChartTopPadding + widget.height;
final double yLabelWidth = _getRightMargin(context);
final double totalWidth = widget.width;

_blockWidth ??= (totalWidth - yLabelWidth) / viewModeLimitDay;

final innerSize = Size(
_blockWidth! * max(dayCount!, viewModeLimitDay),
double.infinity,
Expand Down Expand Up @@ -492,7 +475,6 @@ class ChartState extends State<Chart>
),
);
}

Widget _buildHorizontalScrollView({
required Widget child,
required Key key,
Expand All @@ -515,7 +497,6 @@ class ChartState extends State<Chart>
),
);
}

Widget _buildAnimatedBox({
Widget? child,
required double width,
Expand All @@ -534,7 +515,6 @@ class ChartState extends State<Chart>
begin: 0,
end: _heightForAlignTop,
).animate(_sizeAnimation);

return AnimatedBuilder(
animation: _sizeAnimation,
builder: (context, child) {
Expand All @@ -559,7 +539,6 @@ class ChartState extends State<Chart>
child: child,
);
}

CustomPainter _buildYLabelPainter(BuildContext context, double topPosition) {
switch (widget.chartType) {
case ChartType.time:
Expand Down Expand Up @@ -616,7 +595,7 @@ class ChartState extends State<Chart>
context: context,
tooltipCallback: _tooltipCallback,
dataList: processedData,
barColor: widget.barColor,
barColor: widget.chartStyle?.barColor,
topHour: topHour!,
bottomHour: bottomHour!,
dayCount: dayCount,
Expand All @@ -628,7 +607,7 @@ class ChartState extends State<Chart>
repaint: _scrollOffsetNotifier,
context: context,
dataList: processedData,
barColor: widget.barColor,
barColor: widget.chartStyle?.barColor,
topHour: topHour!,
bottomHour: bottomHour!,
tooltipCallback: _tooltipCallback,
Expand Down
17 changes: 17 additions & 0 deletions lib/src/components/chart_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'dart:ui';

class ChartStyle {
final Color? barColor;
final Color? tooltipBackgroundColor;
final Color? labelColor;
final Color? verticalGridColor;
final Color? horizontalGridColor;

const ChartStyle({
this.barColor,
this.tooltipBackgroundColor,
this.labelColor,
this.verticalGridColor,
this.horizontalGridColor,
});
}
12 changes: 7 additions & 5 deletions lib/src/components/painter/chart_engine.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:math' as math;

import 'package:flutter/material.dart';
import '../view_mode.dart';
import 'package:time_chart/time_chart.dart';
import '../translations/translations.dart';

const double kYLabelMargin = 12.0;
Expand All @@ -14,10 +14,10 @@ const double kLineStrokeWidth = 0.8;
const double kBarWidthRatio = 0.7;
const double kBarPaddingWidthRatio = (1 - kBarWidthRatio) / 2;

const Color kLineColor1 = Color(0x44757575);
const Color kLineColor2 = Color(0x77757575);
const Color kLineColor3 = Color(0xAA757575);
const Color kTextColor = Color(0xFF757575);
Color kLineColor1 = Color(0x44757575);
Color kLineColor2 = Color(0x77757575);
Color kLineColor3 = Color(0xAA757575);
Color kTextColor = Color(0xFF757575);

abstract class ChartEngine extends CustomPainter {
static const int toleranceDay = 1;
Expand All @@ -28,6 +28,7 @@ abstract class ChartEngine extends CustomPainter {
required this.viewMode,
this.firstValueDateTime,
required this.context,
this.chartStyle,
super.repaint,
}) : dayCount = math.max(dayCount ?? -1, viewMode.dayCount),
translations = Translations(context);
Expand All @@ -38,6 +39,7 @@ abstract class ChartEngine extends CustomPainter {
final DateTime? firstValueDateTime;
final BuildContext context;
final Translations translations;
final ChartStyle? chartStyle;

int get currentDayFromScrollOffset {
if (!scrollController!.hasClients) return 0;
Expand Down
Loading