I am using this plugin for creating a pie chart. The label are shown perfectly when there are only 2 divisions but when they increase only 2 labels are shown rest are not.
My Code:-
final List<ChartData> chartData=[ChartData('abc;, 15),ChartData('uvw', 15),ChartData('xyz', 15)];
class ChartData {
ChartData(this.x, this.y, [this.color]);
final String x;
final double y;
final Color color;
}
SfCircularChart(
series: <CircularSeries>[
DoughnutSeries<ChartData, String>(
dataSource: chartData,
pointColorMapper:(ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
startAngle: 90,
endAngle: 360,
dataLabelMapper: (ChartData data, _) => data.x,
radius: '45%',
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelPosition: ChartDataLabelPosition.outside,
labelAlignment: ChartDataLabelAlignment.auto,
textStyle: GoogleFonts.gugi(
textStyle: TextStyle(
),
),
),
)
]
),
Related
first time asking a question here. I would like to how to remove the extra spacing around the SfCircularChart from syncfusion_flutter_charts package.
Container(
// Wrapping around fixed size Container
width: 200,
height: 200,
color: Colors.red,
child: SfCircularChart(
// Setting the margin to zero
margin: EdgeInsets.zero,
series: <CircularSeries>[
PieSeries<Category, String>(
dataSource: dailyEarningList,
xValueMapper: (Category data, _) => data.name,
yValueMapper: (Category data, _) => data.value,
dataLabelSettings: DataLabelSettings(
isVisible: true,
),
),
],
),
)
Image
PieSeries<Category, String>(
radius: "100",
dataSource: [Category(["a", "b", "c"])],
xValueMapper: (Category data, _) => "d",
yValueMapper: (Category data, _) => 1,
dataLabelSettings: const DataLabelSettings(
isVisible: true,
),
),
The library has a radius parameter. It's a string. I do not understand why it's a string. In your example if you set it to "100", it will match the container.
Need to show no data available text in place of bar which has zero value , y axis labels are
string and x axis are integers
please refer below for the 1st image is acutal result and 2nd image is expected result . 1st image in which empty place which has zero value instead of empty place need to show no data available text
SfCartesianChart(
crosshairBehavior: _crosshairBehavior,
primaryXAxis: CategoryAxis(
majorTickLines: MajorTickLines(size: 20, width: 0),
axisBorderType: AxisBorderType.withoutTopAndBottom,
labelAlignment: LabelAlignment.center,
borderWidth: 2.0,
labelStyle: TextStyle(
fontFamily: 'Roboto',
fontSize: 14,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w500),
//maximumLabelWidth: 100,
labelPosition: ChartDataLabelPosition.outside,
borderColor: Colors.blueGrey[800]),
primaryYAxis: CategoryAxis(
plotBands: <PlotBand>[
PlotBand(
isVisible: widget.isFleetAverageVisible,
start: 30,
end: 29,
borderWidth: 0.3,
borderColor: Colors.black,
)
],
interval: 25,
maximumLabels: 4,
maximum: 100,
minimum: 0,
majorTickLines: MajorTickLines(size: 15, width: 0),
majorGridLines: MajorGridLines(dashArray: [5, 5]),
),
series: stackedWidget(sortSelected != null
? sortSelected == true
? SortingOrder.ascending
: SortingOrder.descending
: SortingOrder.none),
legend: Legend(
isVisible: true,
position: LegendPosition.bottom,
overflowMode: LegendItemOverflowMode.wrap,
),
onLegendTapped: (LegendTapArgs args) {
},
),
List<ChartSeries> stackedWidget(SortingOrder sortingOrder) {
return <ChartSeries>[
StackedBarSeries<ChartData, String>(
sortingOrder: sortingOrder,
legendIconType: LegendIconType.horizontalLine,
legendItemText: "series1",
width: 0.3,
spacing: 0.2,
dataSource: chartData,
//list of data
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y1,
sortFieldValueMapper: (ChartData sales, _) => sales.y1,
color: Color.fromRGBO(51, 102, 255, 1))
];
}
Try giving the DataLabelSettings() to the dataLabelSettings: property on StackedBarSeries():
List<ChartSeries> stackedWidget(SortingOrder sortingOrder) {
return <ChartSeries>[
StackedBarSeries<ChartData, String>(
dataLabelSettings: DataLabelSettings(
builder: (
data,
point,
series,
pointIndex,
seriesIndex,
) {
if (chartData[pointIndex].y == 0 || chartData[pointIndex].y == null) {
return Row(children: const [
Icon(Icons.warning_amber_outlined),
Text("No data available"),
]);
} else {
return const SizedBox();
}
},
isVisible: true,
),
sortingOrder: sortingOrder,
legendIconType: LegendIconType.horizontalLine,
legendItemText: "series1",
width: 0.3,
spacing: 0.2,
dataSource: chartData,
//list of data
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y1,
sortFieldValueMapper: (ChartData sales, _) => sales.y1,
color: Color.fromRGBO(51, 102, 255, 1))
];
}
I am using this SfCartesianChart in flutter and here I want to show the legend name horizontally on top of the chart like father, mother, son, and daughter. I don't want to show it vertically. and I also want to change the icon which presents the legend name. I want to show it in the color fill box in front of the legend name. like giving an example image.
how can I do this? please suggest to me some idea.
I want to show it like this:
class _StackedBarState extends State<StackedBar> {
late List<ExpenseData> _chartData;
late TooltipBehavior _tooltipBehavior;
#override
void initState() {
_chartData = getChartData();
_tooltipBehavior = TooltipBehavior(enable: true);
super.initState();
}
#override
Widget build(BuildContext context) {
return SfCartesianChart(
title: ChartTitle(text: "Chart Title"),
legend: Legend(isVisible: true),
tooltipBehavior: _tooltipBehavior,
series: <ChartSeries>[
StackedBarSeries<ExpenseData, String>(
dataSource: _chartData,
xValueMapper: (ExpenseData exp, _) => exp.expenseCategory,
yValueMapper: (ExpenseData exp, _) => exp.father,
dataLabelSettings: DataLabelSettings(isVisible:true, showCumulativeValues: true),
name: 'father',color: Colors.green,width: 0.4 ,
markerSettings: MarkerSettings(isVisible: true)),
StackedBarSeries<ExpenseData, String>(
dataSource: _chartData,
xValueMapper: (ExpenseData exp, _) => exp.expenseCategory,
yValueMapper: (ExpenseData exp, _) => exp.mother,
dataLabelSettings: DataLabelSettings(isVisible:true, showCumulativeValues: true),
name: "Mother",color: Colors.yellowAccent,width: 0.4 ,
markerSettings: MarkerSettings(isVisible: true)),
StackedBarSeries<ExpenseData, String>(
dataSource: _chartData,
xValueMapper: (ExpenseData exp, _) => exp.expenseCategory,
yValueMapper: (ExpenseData exp, _) => exp.son,
dataLabelSettings: DataLabelSettings(isVisible:true, showCumulativeValues: true),
name: "son",color: Colors.red,width: 0.4 ,
markerSettings: MarkerSettings(isVisible: true)),
StackedBarSeries<ExpenseData, String>(
dataSource: _chartData,
xValueMapper: (ExpenseData exp, _) => exp.expenseCategory,
yValueMapper: (ExpenseData exp, _) => exp.daughter,
dataLabelSettings: DataLabelSettings(isVisible:true, showCumulativeValues: true),
name: 'daughter',color: Colors.orange,width: 0.4 ,
markerSettings: MarkerSettings(isVisible: true)),
],
primaryXAxis: CategoryAxis(),
);
}
List<ExpenseData> getChartData() {
final List<ExpenseData> charData = [
ExpenseData('others', 55, 30, 65, 80),
ExpenseData('gaurav shankar', 25, 40, 56, 75),
ExpenseData('bal kishor', 15, 50, 36, 89),
ExpenseData('shashi singh', 45, 60, 56, 89),
ExpenseData('santosh kumar', 30, 10, 60, 90),
];
return charData;
}
}
class ExpenseData {
ExpenseData(
this.expenseCategory,
this.father,
this.mother,
this.son,
this.daughter,
);
final String expenseCategory;
final num father;
final num mother;
final num son;
final num daughter;
}
Just set the Legend.position to LegendPosition.top like so:
legend: Legend(isVisible: true, position: LegendPosition.top),
This is the result:
I have a use case where I have multiple Spline charts in the same picture (see image). As you can see in the image, I need to show a flag marker only in the center curve, but not on the adjacent graphs. I have implemented similar behavior in the image, but I'm not able to remove the marker from the 1st & 3rd graph.
#override
Widget build(BuildContext context) {
final chartData = <_ChartData>[...];
final chartData2 = <_ChartData2>[...];
final chartData3 = <_ChartData3>[...];
return SfCartesianChart(
/// ... Some other props
trackballBehavior: _getTrackBallBehavior(),
series: <ChartSeries>[
SplineAreaSeries<_ChartData2, int>(
dataSource: chartData2,
xValueMapper: (_ChartData2 data, _) => data.x,
yValueMapper: (_ChartData2 data, _) => data.y,
/// INDIVIDUAL LEVEL MARKER SETTING --- not overriding the global one below
markerSettings: const TrackballMarkerSettings(
markerVisibility: TrackballVisibilityMode.hidden,
shape: DataMarkerType.none,
),
),
SplineSeries<_ChartData, int>(
dataSource: chartData,
xValueMapper: (_ChartData data, _) => data.x,
yValueMapper: (_ChartData data, _) => data.y,
),
SplineAreaSeries<_ChartData3, int>(
dataSource: chartData3,
xValueMapper: (_ChartData3 data, _) => data.x,
yValueMapper: (_ChartData3 data, _) => data.y,
),
],
);
}
TrackballBehavior _getTrackBallBehavior() {
return TrackballBehavior(
enable: true,
/// .... some other props
tooltipSettings: const InteractiveTooltip(
enable: true,
arrowLength: 0,
arrowWidth: 0,
),
/// GLOBAL MARKER SETTING
markerSettings: const TrackballMarkerSettings(
markerVisibility: TrackballVisibilityMode.visible,
shape: DataMarkerType.image,
width: 10,
height: 10,
image: CachedNetworkImageProvider(Images.targetFlagWhite),
),
builder: (ctx, details) {
if (details.seriesIndex == 0 || details.seriesIndex == 2)
return Text('Rs.1304', style: AppText.text14w600Title);
return Container(
width: 83.w,
height: 28.h,
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h),
decoration: BoxDecoration(
/// Some decore props
),
child: Text('Rs..1344', style: AppText.text14w600Title),
);
},
);
}
How can achieve that? Or is there a workaround for it?
I suggest you use the onTrackballPositionChanging callback to hide the trackball marker for the specific series 1st and 3rd. In this callback you can get or set the x and y position for each marker, here we have set the marker x and y position value as double.infinity when the series index is 0 and 2 otherwise it is in actual value. We have attached the code snippet below for your reference.
Screenshot:
Code snippet:
onTrackballPositionChanging: (args) {
if (args.chartPointInfo.seriesIndex != 1) {
args.chartPointInfo.markerXPos = double.infinity;
args.chartPointInfo.markerYPos = double.infinity;
}
}
I'm using RadialBarSeries() inside SfCircularChart().
After calling Legend() (in the property legend in SfCircularChart()),
I got the following:
I want to change these circular icons to normal square icons.
This is my code:
child: SfCircularChart(
legend: Legend(
isVisible: true,
overflowMode: LegendItemOverflowMode.wrap,
position: LegendPosition.left,
),
series: <CircularSeries>[
RadialBarSeries<Qualification, String>(
dataLabelSettings: DataLabelSettings(isVisible: true),
dataSource: _qualifications,
xValueMapper: (Qualification data, _) => data.name,
yValueMapper: (Qualification data, _) => data.value
)
],
)
You can do it as follows.
child: SfCircularChart(
title: ChartTitle(text: 'Advances'),
palette: const <Color>[
Color(0xFFffc107),
Color(0xFF0386E8),
],
legend: Legend(
isVisible: true,
overflowMode: LegendItemOverflowMode.wrap,
position: LegendPosition.left,
),
tooltipBehavior: _tooltipData,
series: <CircularSeries>[
RadialBarSeries<ChartData, String>(
legendIconType: LegendIconType.seriesType,
dataSource: _chartData,
xValueMapper: (ChartData data, _) => data.name,
yValueMapper: (ChartData data, _) => data.value,
dataLabelSettings: const DataLabelSettings(
isVisible: true,
),
enableTooltip: true,
cornerStyle: CornerStyle.endCurve,
maximumValue: 100)
],
),
legendIconType: specifies the shape of the legend.
legendIconType: LegendIconType.seriesType,
legendIconType: LegendIconType.circle,
see more here
Documentation: here