Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null check missing in code: Line chart with hidden legends throws exception #2208

Open
PT10 opened this issue Dec 15, 2024 · 3 comments
Open
Labels
charts Charts component open Open

Comments

@PT10
Copy link

PT10 commented Dec 15, 2024

Bug description

There is a clear issue in the code. When "isVisibleInLegend" is false, null is returned. And then there is no null check in the caller.

chart_series.dart

  @override
  List<LegendItem>? buildLegendItems(int index) {
    final List<LegendItem>? items = super.buildLegendItems(index);
    if (trendlineContainer != null) {
      items!.addAll(trendlineContainer!.buildLegendItems(index, this)!);
    }
    return items;
  }

Here a null check is required on items before calling items!.addAll.

Following is the method from base class which this code calls (super.buildLegendItems) and it can return null.

  @override
  List<LegendItem>? buildLegendItems(int index) {
    if (isVisibleInLegend) {
      final LegendItem legendItem = ChartLegendItem(
        text: legendItemText ?? name,
        iconType: toLegendShapeMarkerType(legendIconType, this),
        iconColor: legendIconColor(),
        iconBorderColor: legendIconBorderColor(),
        iconBorderWidth: legendIconBorderWidth(),
        series: this,
        seriesIndex: index,
        pointIndex: 0,
        isToggled: _isToggled(),
        shader: legendIconShader(),
        overlayMarkerType: markerSettings.isVisible
            ? toShapeMarkerType(markerSettings.shape)
            : null,
        imageProvider: legendIconType == LegendIconType.image
            ? parent?.legend?.image
            : null,
        onTap: handleLegendItemTapped,
        onRender: _handleLegendItemCreated,
      );
      return <LegendItem>[legendItem];
    } else {
      return null;
    }
  }

Steps to reproduce

Any line chart which a single series and show legend flag on.

Code sample

Code sample
chart_series.dart

@OverRide
List? buildLegendItems(int index) {
final List? items = super.buildLegendItems(index);
if (trendlineContainer != null) {
items!.addAll(trendlineContainer!.buildLegendItems(index, this)!);
}
return items;
}

Here a null check is required on items before calling items!.addAll.


Following is the method from base class which this code calls (super.buildLegendItems) and it can return null.

@OverRide
List? buildLegendItems(int index) {
if (isVisibleInLegend) {
final LegendItem legendItem = ChartLegendItem(
text: legendItemText ?? name,
iconType: toLegendShapeMarkerType(legendIconType, this),
iconColor: legendIconColor(),
iconBorderColor: legendIconBorderColor(),
iconBorderWidth: legendIconBorderWidth(),
series: this,
seriesIndex: index,
pointIndex: 0,
isToggled: _isToggled(),
shader: legendIconShader(),
overlayMarkerType: markerSettings.isVisible
? toShapeMarkerType(markerSettings.shape)
: null,
imageProvider: legendIconType == LegendIconType.image
? parent?.legend?.image
: null,
onTap: handleLegendItemTapped,
onRender: _handleLegendItemCreated,
);
return [legendItem];
} else {
return null;
}
}



Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Stack Traces

Stack Traces
[Add the Stack Traces here]

On which target platforms have you observed this bug?

Web

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.1, on macOS 14.3.1 23D60 darwin-arm64, locale en-IN)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/to/macos-android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.2)
[✓] VS Code (version 1.86.2)
[✓] Connected device (3 available)
[✓] Network resources

! Doctor found issues in 1 category.
@LavanyaGowtham2021 LavanyaGowtham2021 added charts Charts component open Open labels Dec 16, 2024
@PT10 PT10 changed the title Line chart with one series throws exception Null check missing in code: Line chart with hidden labels throws exception Dec 17, 2024
@PT10 PT10 changed the title Null check missing in code: Line chart with hidden labels throws exception Null check missing in code: Line chart with hidden legends throws exception Dec 18, 2024
@Kaviyarasansf4298
Copy link

Hi,

We have checked the mentioned scenario and tried to replicate the reported it in Charts widget with version 28.1.35 by
1.Tested by toggling the series legend
2.Tested the trendline legend by setting false in load time and true in dynamic time and vice versa.
However, we were unable to reproduce the issue on our end. We have attached the sample we used to test the scenario. Kindly review the attached sample, and if you are still encountering the issue, we request that you replicate it within the provided sample and share more details about the specific scenario in which the issue occurs. This will allow us to assist you more effectively.

Regards,
Kaviyarasan Arumugam.

BoldDesk_667957

bd_667957.zip

@PT10
Copy link
Author

PT10 commented Dec 19, 2024

Modified your code to reproduce the issue. Have a look.

added isVisibleInLegend: false, in series

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Line Series with Legend',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool enableIsVisibleInLegend = false;
  final List<ChartData> chartData = [
    ChartData(DateTime(2024, 1, 1), 35),
    ChartData(DateTime(2024, 2, 1), 40),
    ChartData(DateTime(2024, 3, 1), 55),
    ChartData(DateTime(2024, 4, 1), 60),
    ChartData(DateTime(2024, 5, 1), 50),
    ChartData(DateTime(2024, 6, 1), 70),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Line Series with Legend'),
      ),
      body: Center(
        child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(16),
              child: SfCartesianChart(
                primaryXAxis: DateTimeAxis(),
                onLegendTapped: (legendTapArgs) {},
                legend: const Legend(
                    overflowMode: LegendItemOverflowMode.wrap,
                    toggleSeriesVisibility: false,
                    isVisible: true,
                    position: LegendPosition.bottom),
                series: <ColumnSeries<ChartData, DateTime>>[
                  ColumnSeries<ChartData, DateTime>(
                    dataSource: chartData,
                    isVisibleInLegend: false,
                    trendlines: [
                      Trendline(isVisibleInLegend: enableIsVisibleInLegend)
                    ],
                    xValueMapper: (ChartData data, _) => data.x,
                    yValueMapper: (ChartData data, _) => data.y,
                    dataLabelSettings: DataLabelSettings(isVisible: false),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final DateTime x;
  final double? y;
}

@Kaviyarasansf4298
Copy link

Hi @PT10 ,

We have resolved the issue where a null value was returned when disabling the legend of the trendline at load time in the SfCartesianChart. The fix has been moved to the upcoming weekly patch release, scheduled for December 24, 2024. We appreciate your patience and understanding until then.

Regards,
Kaviyarasan Arumugam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
charts Charts component open Open
Projects
None yet
Development

No branches or pull requests

3 participants