diff --git a/.gitignore b/.gitignore
index e9b2ec3..7859d28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,10 +15,8 @@
*.iws
.idea/
-# The .vscode folder contains launch configuration and tasks you configure in
-# VS Code which you may wish to be included in version control, so this line
-# is commented out by default.
-#.vscode/
+# VSCode related
+.vscode/
### Flutter ###
# Flutter/Dart/Pub related
diff --git a/README.md b/README.md
index efd8bfe..011fd26 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,8 @@ barItemBuilder: (data) {
The `data` that’s passed into the builder can be used to build different kind of item based on the item value (`data.item.value`), his index in data (`data.itemIndex`) or based on which data list it belongs to (`data.listIndex`).
-Besides builder, the other useful parameters in item options are `maxBarWidth` , `minBarWidth` , `startPosition` and `padding`.
+Besides builder, the other useful parameters in item options are `maxBarWidth` , `minBarWidth` , `startPosition` , `padding` and `widthCalculator`.
+`widthCalculator` is used in scrollable charts when `visibleItems` is not `null` and it provides a way to control the width of items.
If you want to listen to **item taps** you can do it by setting `ChartBehaviour(onItemClicked)` - you can read more about ChartBehaviour below.
In case of a WidgetItemOptions, you could also provide GestureDetectors and Buttons and they will all work.
@@ -106,8 +107,8 @@ In case of a WidgetItemOptions, you could also provide GestureDetectors and Butt
Decorations enhance and complete the look of the chart. Everything that’s drawn on a chart, and it’s not a chart item is considered a decoration. So that means a lot of the chart will be a decoration. Just like with the items, you can use **WidgetDecoration** to draw any kind of the decoration, but the most common cases for decoration are already made on a canvas and ready to be used:
| | | |
-:------: | :------: | :------:
-[![horizontal_decoration] Horizontal decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#horizontal-decoration-golden) | [![vertical_decoration] Vertical decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#vertical-decoration-golden) | [![grid_decoration] Grid decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#grid-decoration-golden)
+:------: | :------: | :------:
+[![horizontal_decoration] Horizontal decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#horizontal-decoration-golden) | [![vertical_decoration] Vertical decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#vertical-decoration-golden) | [![grid_decoration] Grid decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#grid-decoration-golden)
[![sparkline_decoration] Sparkline decoration](https://github.com/infinum/flutter-charts/blob/master/test/golden/GOLDENS.md#sparkline-decoration-golden) |
@@ -139,9 +140,10 @@ You can add padding that equals the chart margins which will set you to the star
## Chart behaviour
-Chart behaviour has just two parameters:
+Chart behaviour has just three parameters:
- `isScrollable` - will render a chart that can support scrolling. You still need to wrap it with SingleChildScrollView.
+- `visibleItems` - used when `isScrollable` is set to `true`. Indicates how many items should visible on the screen
- `onItemClicked` - when set the tap events on items are registered and will invoke this method.
If you're using WidgetItemOptions, you could set a gesture detector there, but this works with both BarItemOptions, BubbleItemOptions and WidgetItemOptions.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 043a519..9198f69 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -41,4 +41,5 @@ analyzer:
exclude:
- "bin/cache/**"
- "lib/assets.dart"
-# - "example/**"
\ No newline at end of file
+# - "example/**"
+# - "charts_web/**"
diff --git a/example/lib/charts/scrollable_chart_screen.dart b/example/lib/charts/scrollable_chart_screen.dart
index b6f058e..2913567 100644
--- a/example/lib/charts/scrollable_chart_screen.dart
+++ b/example/lib/charts/scrollable_chart_screen.dart
@@ -90,7 +90,8 @@ class _ScrollableChartScreenState extends State {
},
),
behaviour: ChartBehaviour(
- isScrollable: _isScrollable,
+ scrollSettings:
+ _isScrollable ? ScrollSettings() : ScrollSettings.none(),
onItemClicked: (item) {
setState(() {
_selected = item.itemIndex;
diff --git a/example/lib/charts/scrollable_visible_items_chart_screen.dart b/example/lib/charts/scrollable_visible_items_chart_screen.dart
new file mode 100644
index 0000000..0c09d18
--- /dev/null
+++ b/example/lib/charts/scrollable_visible_items_chart_screen.dart
@@ -0,0 +1,216 @@
+import 'dart:math';
+
+import 'package:charts_painter/chart.dart';
+import 'package:example/widgets/candle_chart.dart';
+import 'package:example/widgets/chart_options.dart';
+import 'package:example/widgets/counter_item.dart';
+import 'package:example/widgets/toggle_item.dart';
+import 'package:flutter/material.dart';
+
+class CandleItem {
+ CandleItem(this.min, this.max);
+
+ final double max;
+ final double min;
+}
+
+class ScrollableVisibleItemsChartScreen extends StatefulWidget {
+ ScrollableVisibleItemsChartScreen({Key? key}) : super(key: key);
+
+ @override
+ _ScrollableVisibleItemsChartScreenState createState() =>
+ _ScrollableVisibleItemsChartScreenState();
+}
+
+class _ScrollableVisibleItemsChartScreenState
+ extends State {
+ List _values = [];
+ double targetMax = 0;
+ double targetMin = 0;
+
+ bool _showValues = false;
+ int minItems = 25;
+ int? _selected;
+ bool _isScrollable = true;
+ int _visibleItems = 6;
+
+ @override
+ void initState() {
+ super.initState();
+ _updateValues();
+ }
+
+ void _updateValues() {
+ final Random _rand = Random();
+ final double _difference = _rand.nextDouble() * 15;
+ final double _max = 8 + _difference;
+
+ targetMax = _max * 0.75 + (_rand.nextDouble() * _max * 0.25);
+ targetMin = targetMax - (3 + (_rand.nextDouble() * (_max / 2)));
+ _values.addAll(List.generate(minItems, (index) {
+ double _value = 2 + _rand.nextDouble() * _difference;
+ return CandleItem(_value, _value + 2 + _rand.nextDouble() * 4);
+ }));
+ }
+
+ void _addValues() {
+ _values = List.generate(minItems, (index) {
+ if (_values.length > index) {
+ return _values[index];
+ }
+ double _value = 2 + Random().nextDouble() * targetMax;
+ return CandleItem(_value, _value + 2 + Random().nextDouble() * 4);
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(
+ 'Candle chart',
+ ),
+ ),
+ body: Column(
+ children: [
+ Center(
+ child: Padding(
+ padding: const EdgeInsets.all(24.0),
+ child: SingleChildScrollView(
+ scrollDirection: Axis.horizontal,
+ physics: _isScrollable
+ ? ScrollPhysics()
+ : NeverScrollableScrollPhysics(),
+ child: CandleChart(
+ data: _values,
+ height: MediaQuery.of(context).size.height * 0.4,
+ width: MediaQuery.of(context).size.width - 48,
+ dataToValue: (CandleItem value) =>
+ CandleValue(value.min, value.max),
+ chartItemOptions: BarItemOptions(
+ minBarWidth: 10.0,
+ padding: EdgeInsets.symmetric(horizontal: 2.0),
+ barItemBuilder: (_) {
+ return BarItem(
+ color: Theme.of(context)
+ .colorScheme
+ .primary
+ .withOpacity(1.0),
+ radius: BorderRadius.all(
+ Radius.circular(100.0),
+ ),
+ );
+ },
+ ),
+ chartBehaviour: ChartBehaviour(
+ scrollSettings: _isScrollable
+ ? ScrollSettings(visibleItems: _visibleItems.toDouble())
+ : ScrollSettings.none(),
+ onItemClicked: (item) {
+ setState(() {
+ _selected = item.itemIndex;
+ });
+ },
+ ),
+ backgroundDecorations: [
+ GridDecoration(
+ showHorizontalValues: _showValues,
+ showVerticalGrid: true,
+ showVerticalValues: _showValues,
+ verticalValuesPadding: EdgeInsets.only(left: 8.0),
+ horizontalAxisStep: 5,
+ verticalTextAlign: TextAlign.start,
+ gridColor: Theme.of(context)
+ .colorScheme
+ .primaryContainer
+ .withOpacity(0.2),
+ textStyle: Theme.of(context)
+ .textTheme
+ .caption!
+ .copyWith(fontSize: 13.0),
+ ),
+ ],
+ foregroundDecorations: [
+ ValueDecoration(
+ textStyle: TextStyle(color: Colors.red),
+ alignment: Alignment.topCenter,
+ ),
+ ValueDecoration(
+ textStyle: TextStyle(color: Colors.red),
+ alignment: Alignment.bottomCenter,
+ valueGenerator: (item) => item.min ?? 0,
+ ),
+ SelectedItemDecoration(
+ _selected,
+ backgroundColor: Theme.of(context)
+ .scaffoldBackgroundColor
+ .withOpacity(0.5),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ Flexible(
+ child: ChartOptionsWidget(
+ onRefresh: () {
+ setState(() {
+ _values.clear();
+ _updateValues();
+ });
+ },
+ onAddItems: () {
+ setState(() {
+ minItems += 4;
+ _addValues();
+ });
+ },
+ onRemoveItems: () {
+ setState(() {
+ if (_values.length > 4) {
+ minItems -= 4;
+ _values.removeRange(_values.length - 4, _values.length);
+ }
+ });
+ },
+ toggleItems: [
+ ToggleItem(
+ title: 'Axis values',
+ value: _showValues,
+ onChanged: (value) {
+ setState(() {
+ _showValues = value;
+ });
+ },
+ ),
+ ToggleItem(
+ value: _isScrollable,
+ title: 'Scrollable',
+ onChanged: (value) {
+ setState(() {
+ _isScrollable = value;
+ });
+ },
+ ),
+ CounterItem(
+ title: 'Visible items',
+ value: _visibleItems,
+ onMinus: () {
+ setState(() {
+ _visibleItems = max(1, _visibleItems - 1);
+ });
+ },
+ onPlus: () {
+ setState(() {
+ _visibleItems = min(36, _visibleItems + 1);
+ });
+ },
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 061a88c..fe5c1ea 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -2,6 +2,7 @@ import 'package:charts_painter/chart.dart';
import 'package:example/chart_types.dart';
import 'package:example/charts/bar_target_chart_screen.dart';
import 'package:example/charts/migration_chart_screen.dart';
+import 'package:example/charts/scrollable_visible_items_chart_screen.dart';
import 'package:example/complex/complex_charts.dart';
import 'package:example/showcase/ios_charts.dart';
import 'package:example/showcase/showcase_charts.dart';
@@ -228,6 +229,47 @@ class ShowList extends StatelessWidget {
},
),
Divider(),
+ ListTile(
+ title: Text('Scrollable with visible items'),
+ trailing: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8.0),
+ child: Container(
+ width: 100.0,
+ child: Chart(
+ state: ChartState(
+ data: ChartData.fromList(
+ [1, 3, 4, 2, 7, 6, 2, 5, 4, 2, 9, 10, 2, 4, 8, 7, 7, 6, 1]
+ .map((e) =>
+ CandleValue(e.toDouble() + 6, e.toDouble()))
+ .toList(),
+ axisMax: 15,
+ ),
+ itemOptions: BarItemOptions(
+ barItemBuilder: (_) {
+ return BarItem(
+ radius: BorderRadius.all(Radius.circular(12.0)),
+ color: Theme.of(context).colorScheme.secondary,
+ );
+ },
+ padding: const EdgeInsets.symmetric(horizontal: 2.0),
+ ),
+ backgroundDecorations: [
+ GridDecoration(
+ verticalAxisStep: 1,
+ horizontalAxisStep: 3,
+ gridColor: Theme.of(context).dividerColor,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ onTap: () {
+ Navigator.of(context).push(MaterialPageRoute(
+ builder: (_) => ScrollableVisibleItemsChartScreen()));
+ },
+ ),
+ Divider(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text(
diff --git a/example/lib/widgets/candle_chart.dart b/example/lib/widgets/candle_chart.dart
index 7352a53..0b14527 100644
--- a/example/lib/widgets/candle_chart.dart
+++ b/example/lib/widgets/candle_chart.dart
@@ -11,6 +11,7 @@ class CandleChart extends StatelessWidget {
required this.data,
required this.dataToValue,
this.height = 240.0,
+ this.width,
this.backgroundDecorations = const [],
this.chartBehaviour = const ChartBehaviour(),
this.chartItemOptions = const BarItemOptions(),
@@ -24,6 +25,7 @@ class CandleChart extends StatelessWidget {
final DataToValue dataToValue;
final double height;
+ final double? width;
final List backgroundDecorations;
final List foregroundDecorations;
final ChartBehaviour chartBehaviour;
@@ -36,6 +38,7 @@ class CandleChart extends StatelessWidget {
Widget build(BuildContext context) {
return AnimatedChart(
height: height,
+ width: width,
duration: const Duration(milliseconds: 450),
state: ChartState(
data: ChartData(_mappedValues),
diff --git a/example/lib/widgets/counter_item.dart b/example/lib/widgets/counter_item.dart
new file mode 100644
index 0000000..9fbda6a
--- /dev/null
+++ b/example/lib/widgets/counter_item.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+
+class CounterItem extends StatelessWidget {
+ CounterItem(
+ {required this.title,
+ required this.value,
+ required this.onMinus,
+ required this.onPlus,
+ Key? key})
+ : super(key: key);
+
+ final int value;
+ final String title;
+ final VoidCallback onMinus;
+ final VoidCallback onPlus;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ child: ListTile(
+ title: Text(title),
+ trailing: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ InkWell(
+ onTap: onMinus,
+ child: AspectRatio(
+ aspectRatio: 1,
+ child: Icon(Icons.remove),
+ ),
+ ),
+ InkWell(
+ onTap: onPlus,
+ child: AspectRatio(
+ aspectRatio: 1,
+ child: Icon(Icons.add),
+ ),
+ ),
+ AspectRatio(
+ aspectRatio: 1,
+ child: Center(child: Text('$value')),
+ ),
+ ],
+ ),
+ ));
+ }
+}
diff --git a/lib/chart.dart b/lib/chart.dart
index dfdb4e0..9dc873d 100644
--- a/lib/chart.dart
+++ b/lib/chart.dart
@@ -27,6 +27,7 @@ part 'chart/model/geometry/chart_item.dart';
/// Theme
part 'chart/model/theme/chart_behaviour.dart';
+part 'chart/model/theme/scroll_settings.dart';
part 'chart/model/theme/item_theme/bar/bar_item_options.dart';
part 'chart/model/theme/item_theme/item_options.dart';
part 'chart/model/theme/item_theme/bar/bar_item.dart';
diff --git a/lib/chart/model/theme/chart_behaviour.dart b/lib/chart/model/theme/chart_behaviour.dart
index 22b480e..e6f9499 100644
--- a/lib/chart/model/theme/chart_behaviour.dart
+++ b/lib/chart/model/theme/chart_behaviour.dart
@@ -4,37 +4,30 @@ part of charts_painter;
/// [isScrollable] - If chart is scrollable then width of canvas is ignored and
/// chart will take any size it needs. Chart has to be wrapped with [SingleChildScrollView]
/// or similar scrollable widget.
-/// [multiValueStack] - Defaults to true, Dictates how items in stack will be shown, if set to true items will stack on
-/// each other, on false they will be side by side.
/// [onItemClicked] - Returns index of clicked item.
class ChartBehaviour {
/// Default constructor for ChartBehaviour
/// If chart is scrollable then it will ignore width limit and it should be wrapped in [SingleChildScrollView]
const ChartBehaviour({
- bool isScrollable = false,
+ this.scrollSettings = const ScrollSettings.none(),
this.onItemClicked,
- }) : _isScrollable = isScrollable ? 1.0 : 0.0;
+ });
- ChartBehaviour._lerp(this._isScrollable, this.onItemClicked);
+ ChartBehaviour._lerp(this.scrollSettings, this.onItemClicked);
- final double _isScrollable;
+ final ScrollSettings scrollSettings;
/// Return index of item clicked. Since graph can be multi value, user
/// will have to handle clicked index to show data they want to show
final ValueChanged? onItemClicked;
/// Return true if chart is currently scrollable
- bool get isScrollable => _isScrollable > 0.5;
+ bool get isScrollable => scrollSettings._isScrollable > 0.5;
/// Animate Behaviour from one state to other
static ChartBehaviour lerp(ChartBehaviour a, ChartBehaviour b, double t) {
- // This values should never return null, this is for null-safety
- // But if it somehow does occur, then revert to default values
- final _scrollableLerp =
- lerpDouble(a._isScrollable, b._isScrollable, t) ?? 0.0;
-
return ChartBehaviour._lerp(
- _scrollableLerp,
+ ScrollSettings.lerp(a.scrollSettings, b.scrollSettings, t),
t > 0.5 ? b.onItemClicked : a.onItemClicked,
);
}
diff --git a/lib/chart/model/theme/item_theme/item_options.dart b/lib/chart/model/theme/item_theme/item_options.dart
index d206d09..14ad1cb 100644
--- a/lib/chart/model/theme/item_theme/item_options.dart
+++ b/lib/chart/model/theme/item_theme/item_options.dart
@@ -29,7 +29,9 @@ abstract class ItemOptions {
this.minBarWidth,
this.startPosition = 0.5,
required this.itemBuilder,
- });
+ }) : assert(maxBarWidth == null ||
+ minBarWidth == null ||
+ maxBarWidth >= minBarWidth);
const ItemOptions._lerp({
required this.geometryPainter,
@@ -53,8 +55,6 @@ abstract class ItemOptions {
final ItemBuilder itemBuilder;
- /// Define color for value, this allows different colors for different values
-
/// Max width of item in the chart
final double? maxBarWidth;
diff --git a/lib/chart/model/theme/item_theme/widget/widget_item_options.dart b/lib/chart/model/theme/item_theme/widget/widget_item_options.dart
index 2bf2a56..cec1b2e 100644
--- a/lib/chart/model/theme/item_theme/widget/widget_item_options.dart
+++ b/lib/chart/model/theme/item_theme/widget/widget_item_options.dart
@@ -64,11 +64,12 @@ class WidgetItemOptions extends ItemOptions {
@override
ItemOptions animateTo(ItemOptions endValue, double t) {
return WidgetItemOptions._lerp(
- widgetItemBuilder: endValue is WidgetItemOptions
- ? endValue.widgetItemBuilder
- : widgetItemBuilder,
- multiValuePadding:
- EdgeInsets.lerp(multiValuePadding, endValue.multiValuePadding, t) ??
- EdgeInsets.zero);
+ widgetItemBuilder: endValue is WidgetItemOptions
+ ? endValue.widgetItemBuilder
+ : widgetItemBuilder,
+ multiValuePadding:
+ EdgeInsets.lerp(multiValuePadding, endValue.multiValuePadding, t) ??
+ EdgeInsets.zero,
+ );
}
}
diff --git a/lib/chart/model/theme/scroll_settings.dart b/lib/chart/model/theme/scroll_settings.dart
new file mode 100644
index 0000000..1cf47bf
--- /dev/null
+++ b/lib/chart/model/theme/scroll_settings.dart
@@ -0,0 +1,30 @@
+part of charts_painter;
+
+class ScrollSettings {
+ const ScrollSettings({
+ this.visibleItems,
+ }) : assert(visibleItems == null || visibleItems > 0,
+ 'visibleItems must be greater than 0'),
+ _isScrollable = 1.0;
+
+ const ScrollSettings.none()
+ : _isScrollable = 0.0,
+ visibleItems = null;
+
+ ScrollSettings._lerp(this._isScrollable, this.visibleItems);
+
+ final double _isScrollable;
+
+ /// Number of visible items on the screen.
+ final double? visibleItems;
+
+ static ScrollSettings lerp(ScrollSettings a, ScrollSettings b, double t) {
+ // This values should never return null, this is for null-safety
+ // But if it somehow does occur, then revert to default values
+ final scrollableLerp =
+ lerpDouble(a._isScrollable, b._isScrollable, t) ?? 0.0;
+ final visibleLerp = lerpDouble(a.visibleItems, b.visibleItems, t);
+
+ return ScrollSettings._lerp(scrollableLerp, visibleLerp);
+ }
+}
diff --git a/lib/chart/widgets/chart_widget.dart b/lib/chart/widgets/chart_widget.dart
index 45e1443..c6da7fc 100644
--- a/lib/chart/widgets/chart_widget.dart
+++ b/lib/chart/widgets/chart_widget.dart
@@ -16,40 +16,78 @@ class _ChartWidget extends StatelessWidget {
final double? width;
final ChartState state;
+ double get _horizontalItemPadding => state.itemOptions.padding.horizontal;
+
+ double _clampItemWidth(double width) {
+ final minBarWidth = state.itemOptions.minBarWidth;
+ final maxBarWidth = state.itemOptions.maxBarWidth;
+
+ if (minBarWidth != null) {
+ return max(minBarWidth, width);
+ }
+
+ if (maxBarWidth != null) {
+ return min(maxBarWidth, width);
+ }
+
+ return width;
+ }
+
+ double _calcItemWidthNonScrollable() {
+ return max(
+ state.itemOptions.minBarWidth ?? 0.0,
+ state.itemOptions.maxBarWidth ?? 0.0,
+ );
+ }
+
+ double _calcItemWidthForScrollable(double frameWidth) {
+ final visibleItems = state.behaviour.scrollSettings.visibleItems;
+ if (visibleItems == null) {
+ return _calcItemWidthNonScrollable();
+ }
+
+ final availableWidth = frameWidth - state.defaultPadding.horizontal;
+ final width = availableWidth / visibleItems - _horizontalItemPadding;
+
+ return _clampItemWidth(max(0, width));
+ }
+
+ double _calcItemWidth(double frameWidth) {
+ // Used for smooth transition between scrollable and non-scrollable chart
+ final sizeTween = Tween(
+ begin: _calcItemWidthNonScrollable(),
+ end: _calcItemWidthForScrollable(frameWidth),
+ );
+
+ return sizeTween.transform(state.behaviour.scrollSettings._isScrollable);
+ }
+
+ Size _calcChartSize(double itemWidth, double frameWidth, double frameHeight) {
+ final listSize = state.data.listSize;
+ final totalItemWidth = itemWidth + _horizontalItemPadding;
+ final listWidth = totalItemWidth * listSize;
+
+ final chartWidth = frameWidth +
+ (listWidth - frameWidth) * state.behaviour.scrollSettings._isScrollable;
+ final finalWidth = chartWidth + state.defaultPadding.horizontal;
+
+ return Size(finalWidth, frameHeight);
+ }
+
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
- // What size does the item want to be?
- final _wantedItemWidth = state.data.items.foldIndexed(0.0,
- (index, double prevValue, _) {
- return max(
- prevValue,
- max(state.itemOptions.minBarWidth ?? 0.0,
- state.itemOptions.maxBarWidth ?? 0.0));
- });
-
- final _width =
+ final frameWidth =
constraints.maxWidth.isFinite ? constraints.maxWidth : width!;
- final _height =
+ final frameHeight =
constraints.maxHeight.isFinite ? constraints.maxHeight : height!;
- final _listSize = state.data.listSize;
-
- final _horizontalPadding = state.data.items.foldIndexed(0.0,
- (index, double prevValue, _) {
- return max(prevValue, state.itemOptions.padding.horizontal);
- });
-
- final _size = Size(
- _width +
- (((_wantedItemWidth + _horizontalPadding) * _listSize) -
- _width) *
- state.behaviour._isScrollable,
- _height);
+ final itemWidth = _calcItemWidth(frameWidth);
+ final size = _calcChartSize(itemWidth, frameWidth, frameHeight);
return Container(
- constraints: BoxConstraints.tight(_size),
+ constraints: BoxConstraints.tight(size),
child: ChartRenderer(state),
);
},