Closed azizainunnajib closed 11 months ago
Hi @azizainunnajib,
We understand that you need to render only the first series at load time and to render all the other respective series while toggling the legend using the legendItemBuilder property. While using the legendItemBuilder property all the series will be in visible at load time itself but it might appear only the first series is rendering as you have given same series name except for the first series and same y values for all the series based on the provided code snippet.
However, we would like to let you know that currently, the legend template doesn't consider the series visibility. So, we have achieved your requirement with the help of a list of Boolean values to represent the series visibility and wrapped the legend template with GestureDetector. We change the seriesVisibility list in its onTap callback based on the tapped series index value and then assign the empty data source value to the corresponding series, which has the series visibility set to false as shown in the code snippet below.
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
late List<ChartDataView> _chartData;
final List<bool> _seriesVisibility = [true, false, false, false, false];
@override
void initState() {
_chartData = [
ChartDataView(
period: DateTime(2000),
loadConsumption: 40,
exportFromGrid: 90,
solar: 50,
importFromGrid: 10,
selfConsumption: 70,
),
ChartDataView(
period: DateTime(2001),
loadConsumption: 20,
exportFromGrid: 30,
solar: 60,
importFromGrid: 30,
selfConsumption: 80,
),
ChartDataView(
period: DateTime(2002),
loadConsumption: 70,
exportFromGrid: 40,
solar: 80,
importFromGrid: 40,
selfConsumption: 30,
),
ChartDataView(
period: DateTime(2003),
loadConsumption: 80,
exportFromGrid: 10,
solar: 20,
importFromGrid: 30,
selfConsumption: 40,
),
ChartDataView(
period: DateTime(2004),
loadConsumption: 60,
exportFromGrid: 40,
solar: 30,
importFromGrid: 20,
selfConsumption: 10,
),
ChartDataView(
period: DateTime(2005),
loadConsumption: 50,
exportFromGrid: 70,
solar: 60,
importFromGrid: 50,
selfConsumption: 40,
),
ChartDataView(
period: DateTime(2006),
loadConsumption: 70,
exportFromGrid: 60,
solar: 90,
importFromGrid: 80,
selfConsumption: 20,
),
ChartDataView(
period: DateTime(2007),
loadConsumption: 90,
exportFromGrid: 80,
solar: 30,
importFromGrid: 50,
selfConsumption: 10,
),
ChartDataView(
period: DateTime(2008),
loadConsumption: 30,
exportFromGrid: 20,
solar: 60,
importFromGrid: 40,
selfConsumption: 60,
),
ChartDataView(
period: DateTime(2009),
loadConsumption: 50,
exportFromGrid: 60,
solar: 70,
importFromGrid: 80,
selfConsumption: 30,
),
ChartDataView(
period: DateTime(2010),
loadConsumption: 10,
exportFromGrid: 80,
solar: 90,
importFromGrid: 70,
selfConsumption: 90,
),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SfCartesianChart(
primaryXAxis: DateTimeAxis(),
primaryYAxis: NumericAxis(),
legend: Legend(
isVisible: true,
position: LegendPosition.top,
overflowMode: LegendItemOverflowMode.wrap,
legendItemBuilder: (String legendText, dynamic series,
dynamic point, int seriesIndex) {
debugPrint('seriesIndex => $seriesIndex');
debugPrint('legendText => $legendText');
return Padding(
padding: const EdgeInsets.all(10),
child: GestureDetector(
onTap: () {
setState(() {
_seriesVisibility[seriesIndex] =
!_seriesVisibility[seriesIndex];
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.circle,
color: seriesIndex == 0
? Colors.amber
: seriesIndex == 1
? Colors.red
: seriesIndex == 2
? Colors.green
: seriesIndex == 3
? Colors.yellowAccent
: Colors.blue,
size: 10,
),
const SizedBox(width: 10),
Text(
series.name!,
style: TextStyle(
fontSize: 12,
color: _seriesVisibility[seriesIndex]
? Colors.black
: Colors.grey.shade600,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
},
),
series: <CartesianSeries<ChartDataView, DateTime>>[
SplineAreaSeries<ChartDataView, DateTime>(
dataSource: _seriesVisibility[0] ? _chartData : <ChartDataView>[],
isVisible: _seriesVisibility[0],
name: 'Load Consumption',
xValueMapper: (ChartDataView data, _) => data.period,
yValueMapper: (ChartDataView data, _) => data.loadConsumption,
color: Colors.amber,
),
SplineAreaSeries<ChartDataView, DateTime>(
dataSource: _seriesVisibility[1] ? _chartData : <ChartDataView>[],
isVisible: _seriesVisibility[1],
name: 'Export to Grid',
xValueMapper: (ChartDataView data, _) => data.period,
yValueMapper: (ChartDataView data, _) => data.exportFromGrid,
color: Colors.red,
),
SplineAreaSeries<ChartDataView, DateTime>(
dataSource: _seriesVisibility[2] ? _chartData : <ChartDataView>[],
isVisible: _seriesVisibility[2],
name: 'Solar',
xValueMapper: (ChartDataView data, _) => data.period,
yValueMapper: (ChartDataView data, _) => data.solar,
color: Colors.green,
),
SplineAreaSeries<ChartDataView, DateTime>(
dataSource: _seriesVisibility[3] ? _chartData : <ChartDataView>[],
isVisible: _seriesVisibility[3],
name: 'Import from Grid',
xValueMapper: (ChartDataView data, _) => data.period,
yValueMapper: (ChartDataView data, _) => data.importFromGrid,
color: Colors.yellowAccent,
),
SplineAreaSeries<ChartDataView, DateTime>(
dataSource: _seriesVisibility[4] ? _chartData : <ChartDataView>[],
isVisible: _seriesVisibility[4],
name: 'Self Consumption',
xValueMapper: (ChartDataView data, _) => data.period,
yValueMapper: (ChartDataView data, _) => data.selfConsumption,
color: Colors.blue,
),
],
),
),
);
}
}
class ChartDataView {
final DateTime period;
final num loadConsumption;
final num exportFromGrid;
final num solar;
final num importFromGrid;
final num selfConsumption;
ChartDataView({
required this.period,
required this.loadConsumption,
required this.exportFromGrid,
required this.solar,
required this.importFromGrid,
required this.selfConsumption,
});
}
Note: However, your UI appearance is the same as the default legend appearance. Default legend will work for your scenario without any issues. Hence, we also suggest using the default legend instead of the legendItemBuilder, and for the legend icon, you can use the legendIconType property in the series and set the required shape based on your requirement.
Also attached the sample and recording below for your reference and you can modify the sample according to your needs. If you have further queries, please get back to us.
Regards, Hari Hara Sudhan. K. 506132.zip _506132.zip
Hi @sfHariHaraSudhan thanks fo rthe reply and the solution it woks so well. but there's little problem, if i give the tooltip, sometime the tooltip and legend is not working. but i solve it with tooltip builder. even the arrow of tolltips is not perfect. but hope it's fine.
this is the not perfect (in tooltip) I mention earlier.
i have series with 5 SpLineArea. the series is like this.
var series = [SplineAreaSeries<ChartDataView, DateTime>( dataSource: _chartData, isVisible: **true**, name: 'Load Consumption', xValueMapper: (ChartDataView data, _) => data.period, yValueMapper: (ChartDataView data, _) => data.loadConsumption), SplineAreaSeries<ChartDataView, DateTime>( dataSource: _chartData, isVisible: **false**, name: 'Export to Grid', xValueMapper: (ChartDataView data, _) => data.period, yValueMapper: (ChartDataView data, _) => data.loadConsumption), SplineAreaSeries<ChartDataView, DateTime>( dataSource: _chartData, isVisible: **false**, name: 'Export to Grid', xValueMapper: (ChartDataView data, _) => data.period, yValueMapper: (ChartDataView data, _) => data.loadConsumption), SplineAreaSeries<ChartDataView, DateTime>( dataSource: _chartData, isVisible: **false**, name: 'Export to Grid', xValueMapper: (ChartDataView data, _) => data.period, yValueMapper: (ChartDataView data, _) => data.loadConsumption), SplineAreaSeries<ChartDataView, DateTime>( dataSource: _chartData, isVisible: **false**, name: 'Export to Grid', xValueMapper: (ChartDataView data, _) => data.period, yValueMapper: (ChartDataView data, _) => data.loadConsumption) ]
I set it only first data is visible first.
at the first load is fine, the first data is only data visible. but the legend is not grey. then when I click legend, all series is showing.
here I attach the video. https://github.com/syncfusion/flutter-examples/assets/22388427/3dc89b8b-8e48-4201-8b3c-6522a28c8459
*note I digging some code in library, is it maybe because this code? seems wrong because the variable
seriesVisible
is not calculate in that method. here I attach part of library's code.