Description
When I set zoomPanBehavior with autoScrollingDelta in primaryXAxis of 5 and if i have like 7 point to show and set onMarkerRender parameter, I got this error.
════════ Exception caught by rendering library ═════════════════════════════════
The following _CastError was thrown during paint():
Null check operator used on a null value
e:syncfusion_flutter_charts/…/common/marker.dart:337
This is my Code.
Widget _chart(
MuscleProgressSuccessState progressState,
) =>
(progressState.progress?.volumes.isEmpty ?? true)
? _emptyState
: BlocBuilder<SettingsCubit, SettingsState>(
builder: (context, mState) {
final isDark = AppProvider.of(context).isDark;
final gridColor = isDark
? MyColors.darkChartGridLinesColor
: MyColors.chartGridLinesColor;
final textColor = isDark
? MyColors.darkChartTextColor
: MyColors.chartTextColor;
final itemList = progressState.progress?.volumes ?? [];
final items = itemList.sublist(
max(itemList.length - 7, 0),
);
final itemCounts = items.length;
final feelings = progressState.progress?.feelings ?? [];
return Container(
margin: const EdgeInsetsDirectional.only(
start: 16,
end: 24,
top: 24,
bottom: 16,
),
width: double.infinity,
height: double.infinity,
child: SfCartesianChart(
key: UniqueKey(),
plotAreaBorderWidth: 0,
axisLabelFormatter: (details) {
final isY =
details.orientation == AxisOrientation.vertical;
final yValue = details.value
.toDouble()
.getWeight(mState.settings.metrics)
.toDouble()
.toNum;
return ChartAxisLabel(
isY ? yValue : details.actualText,
TextStyle(
color: textColor,
fontFamily: Fonts.alvarEssential,
fontSize: 12,
fontWeight: Fonts.regular,
),
);
},
selectionType: SelectionType.point,
zoomPanBehavior: ZoomPanBehavior(
enablePanning: true,
enablePinching: true,
zoomMode: ZoomMode.x,
enableDoubleTapZooming: true,
),
primaryXAxis: NumericAxis(
autoScrollingDelta: 5,
zoomFactor: .5,
zoomPosition: .5,
enableAutoIntervalOnZooming: true,
maximum: itemCounts.toDouble(),
axisLine: AxisLine(
width: 1,
color: gridColor,
),
interval: 1,
majorGridLines: MajorGridLines(
width: 1,
color: gridColor,
),
majorTickLines: MajorTickLines(
color: AppProvider.of(context).isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2,
size: 4,
width: 4,
),
),
primaryYAxis: NumericAxis(
isVisible: true,
majorGridLines: MajorGridLines(
color: gridColor,
width: 1,
),
axisLine: AxisLine(
width: 1,
color: gridColor,
),
majorTickLines: MajorTickLines(
color: AppProvider.of(context).isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2,
size: 0,
width: 0,
),
minimum: (items.minValue * .8).roundToDouble(),
maximum: (items.maxValue * 1.25).roundToDouble(),
),
trackballBehavior: TrackballBehavior(
enable: true,
markerSettings: const TrackballMarkerSettings(
color: Colors.transparent,
borderColor: Colors.transparent,
borderWidth: 5,
height: 11,
markerVisibility: TrackballVisibilityMode.visible,
width: 11,
shape: DataMarkerType.circle,
),
activationMode: ActivationMode.singleTap,
shouldAlwaysShow: true,
lineDashArray: const [5, 5],
lineType: TrackballLineType.vertical,
lineWidth: 1,
tooltipSettings: InteractiveTooltip(
color: _mainColor(context),
borderColor: _mainColor(context),
),
lineColor: _mainColor(context),
builder: (context, details) {
return BlocBuilder<WeightChartTouchCubit,
WeightChartTouchState>(
builder: (context, state) {
final intData = details.point?.y as int;
final initialIndex = details.point?.x;
final String feelingStr;
if (initialIndex == null ||
initialIndex is! int ||
feelings.isEmpty) {
feelingStr = '';
} else {
int index =
min(feelings.length, initialIndex - 1);
index = max(0, index);
final feeling = feelings[index];
feelingStr = _titles(context)[feeling];
}
return Container(
padding: const EdgeInsets.only(
left: 12,
right: 12,
top: 4,
bottom: 4,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(
width: 1,
color: _mainColor(context),
),
color: Theme.of(context).cardColor,
),
child: Text.rich(
TextSpan(
style: TextStyle(
fontFamily: Fonts.alvarEssential,
fontWeight: Fonts.regular,
color: AppProvider.of(context).isDark
? Theme.of(context)
.textTheme
.bodyText1
?.color
: MyColors.subtitleColor2,
),
children: [
if (feelingStr.isNotEmpty)
TextSpan(
text: '$feelingStr\n',
style: const TextStyle(
fontSize: 13,
),
),
TextSpan(
text: intData
.toDouble()
.getWeight(mState.settings.metrics)
.toDouble()
.toNum,
style: const TextStyle(
fontSize: 15,
),
),
],
),
),
);
},
);
},
tooltipDisplayMode: TrackballDisplayMode.nearestPoint,
),
tooltipBehavior: TooltipBehavior(
enable: false,
),
onMarkerRender: (args) {
final initialIndex = args.pointIndex ?? -1;
final int feelingIndex;
if (feelings.isEmpty) {
feelingIndex = -1;
} else {
int index = min(feelings.length, initialIndex);
index = max(0, index);
final feeling = feelings[index];
feelingIndex = feeling;
}
if (feelingIndex >= 1 && feelingIndex <= 5) {
args.color = _getMarkerColor(context, feelingIndex);
}
},
series: [
AreaSeries<int, int>(
enableTooltip: true,
markerSettings: MarkerSettings(
isVisible: true,
color: _mainColor(context),
borderColor: isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2,
borderWidth: 3,
height: 14,
width: 14,
shape: DataMarkerType.circle,
),
dataSource: items,
xValueMapper: (int weight, _) => _ + 1,
yValueMapper: (int weight, _) => weight,
borderDrawMode: BorderDrawMode.top,
borderWidth: 4,
gradient: LinearGradient(
colors: [
_mainColor(context).withOpacity(.8),
_mainColor(context).withOpacity(0)
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: const [.25, 1],
),
borderColor: _mainColor(context),
),
],
),
);
},
);
Widget get _emptyState => Builder(
builder: (context) {
final isDark = AppProvider.of(context).isDark;
final gridColor = isDark
? MyColors.darkChartGridLinesColor
: MyColors.chartGridLinesColor;
final textColor =
isDark ? MyColors.darkChartTextColor : MyColors.chartTextColor;
final items = [0, 0, 0, 0, 0, 0, 0];
final itemCounts = items.length;
return Container(
margin: const EdgeInsetsDirectional.only(
start: 16,
end: 24,
top: 32,
bottom: 16,
),
width: double.infinity,
height: double.infinity,
child: Blur(
blur: 2,
alignment: Alignment.center,
blurColor: Theme.of(context).backgroundColor,
overlay: Builder(
builder: (context) => Center(
child: MyText(
text: AppLocalizations.of(context)!.empty_chart_data,
fontSize: 20,
fontWeight: Fonts.medium,
),
),
),
child: SfCartesianChart(
plotAreaBorderWidth: 0,
axisLabelFormatter: (details) => ChartAxisLabel(
details.actualText,
TextStyle(
color: textColor,
fontFamily: Fonts.alvarEssential,
fontSize: 12,
fontWeight: Fonts.regular,
),
),
selectionType: SelectionType.point,
primaryXAxis: NumericAxis(
maximum: itemCounts + _xInterval * .2,
axisLine: AxisLine(
width: 1,
color: gridColor,
),
interval: 1,
majorGridLines: MajorGridLines(
width: 1,
color: gridColor,
),
majorTickLines: MajorTickLines(
color: AppProvider.of(context).isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2,
size: 4,
width: 4,
),
),
primaryYAxis: NumericAxis(
isVisible: true,
majorGridLines: MajorGridLines(
color: gridColor,
width: 1,
),
axisLine: AxisLine(
width: 1,
color: gridColor,
),
majorTickLines: MajorTickLines(
color: AppProvider.of(context).isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2,
size: 0,
width: 0,
),
minimum: (items.minValue * .8).roundToDouble(),
maximum: (items.maxValue * 1.25).roundToDouble(),
),
trackballBehavior: TrackballBehavior(
enable: true,
activationMode: ActivationMode.singleTap,
shouldAlwaysShow: true,
lineDashArray: const [5, 5],
lineType: TrackballLineType.vertical,
lineWidth: 1,
tooltipSettings: InteractiveTooltip(
color: _mainColor(context),
borderColor: _mainColor(context),
),
lineColor: _mainColor(context),
builder: (context, details) {
return BlocBuilder<SettingsCubit, SettingsState>(
builder: (context, mState) => BlocBuilder<
WeightChartTouchCubit, WeightChartTouchState>(
builder: (context, state) {
final intData = details.point?.y as int;
return Container(
padding: const EdgeInsets.only(
left: 12,
right: 12,
top: 4,
bottom: 4,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(
width: 1,
color: _mainColor(context),
),
color: Theme.of(context).cardColor,
),
child: Text.rich(
TextSpan(
style: TextStyle(
fontFamily: Fonts.alvarEssential,
fontWeight: Fonts.regular,
color: AppProvider.of(context).isDark
? Theme.of(context)
.textTheme
.bodyText1
?.color
: MyColors.subtitleColor2,
),
children: [
TextSpan(
text: intData
.toDouble()
.getWeight(mState.settings.metrics)
.toDouble()
.toNum,
style: const TextStyle(
fontSize: 15,
),
),
],
),
),
);
},
),
);
},
tooltipDisplayMode: TrackballDisplayMode.nearestPoint,
),
tooltipBehavior: TooltipBehavior(
enable: false,
),
series: [
AreaSeries<int, int>(
dataSource: items,
xValueMapper: (int weight, _) => _ + 1,
yValueMapper: (int weight, _) => weight,
),
],
),
),
);
},
);
double get _xInterval => 1;
Color _mainColor(BuildContext context) => AppProvider.of(context).isDark
? MyColors.darkMentalColor
: MyColors.mentalColor;
Color? _getMarkerColor(BuildContext context, int index) {
switch (index) {
case 0:
return AppProvider.of(context).isDark
? MyColors.darkVeryEasy
: MyColors.veryEasy;
case 1:
return AppProvider.of(context).isDark
? MyColors.darkEasy
: MyColors.easy;
case 2:
return AppProvider.of(context).isDark
? MyColors.darkModerate
: MyColors.moderate;
case 3:
return AppProvider.of(context).isDark
? MyColors.darkHard
: MyColors.hard;
case 4:
return AppProvider.of(context).isDark
? MyColors.darkVeryHard
: MyColors.veryHard;
default:
return AppProvider.of(context).isDark
? Theme.of(context).textTheme.bodyText1?.color
: MyColors.subtitleColor2;
}
}
List<String> _titles(BuildContext context) => [
AppLocalizations.of(context)!.very_easy_label,
AppLocalizations.of(context)!.easy_label,
AppLocalizations.of(context)!.moderate_label,
AppLocalizations.of(context)!.hard_label,
AppLocalizations.of(context)!.very_hard_label,
];
Full Error Log
#15 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1143
#16 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1080
#17 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:996
#21 _invoke (dart:ui/hooks.dart:166:10)
#22 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#23 _drawFrame (dart:ui/hooks.dart:129:31)
(elided 3 frames from dart:async)
The following RenderObject was being processed when the exception was fired: RenderCustomPaint#1d340 relayoutBoundary=up2
RenderObject: RenderCustomPaint#1d340 relayoutBoundary=up2
parentData: (can use size)
constraints: BoxConstraints(0.0<=w<=351.4, 0.0<=h<=330.0)
size: Size(0.0, 0.0)
════════════════════════════════════════════════════════════════════════════════