I have been trying to make an app that represent a graph from values in firebase. I am using onValue.listen to get values when changed. I don't know what exactly happens, but when I change value manually, the same value seems to be repeated multiple times, so not one value is added but multiple in one single event. It is like if the function has been called more than once. I am using syncfusion_flutter_charts to build the graph.
Code for listening:
void getCurrent() {
currentRef.onValue.listen((event) {
if (mounted) {
double currentReading = double.parse(event.snapshot.value.toString());
int listLength = currentChartData.length;
print(currentChartData);
setState(() {
currentChartData
.add(CurrentChartData(listLength, currentReading.round()));
});
}
});
}
code for graph:
SfCartesianChart(
zoomPanBehavior: ZoomPanBehavior(
zoomMode: ZoomMode.x,
maximumZoomLevel: 0.04 * currentChartData.length,
enablePinching: true,
enablePanning: true,
enableSelectionZooming: true),
borderColor: Colors.transparent,
primaryXAxis: NumericAxis(
minimum: 1,
rangePadding: ChartRangePadding.round,
interval: 1.0),
primaryYAxis: NumericAxis(
minimum: 0,
rangePadding: ChartRangePadding.round,
),
series: <ChartSeries<CurrentChartData, int>>[
SplineAreaSeries<CurrentChartData, int>(
dataSource: currentChartData,
xValueMapper: (CurrentChartData data, _) => data.day,
yValueMapper: (CurrentChartData data, _) => data.ppm,
name: 'Methane Concentrations',
gradient: LinearGradient(
colors: [
AppStyle.spline_color,
AppStyle.bg_color.withAlpha(150)
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
SplineSeries(
dataSource: currentChartData,
xValueMapper: (CurrentChartData data, _) => data.day,
yValueMapper: (CurrentChartData data, _) => data.ppm,
color: AppStyle.accent_color,
width: 3,
)
],
),
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.
I have tried creating this bar graph using SfCartesianChart, and have been able to complete 95% of it, but unable to remove the middle labels.
...
Lobo,
Greetings from Syncfusion.
We have validated your query and we have achieved your requirement by using the axisLabelFormatter callback in axis. We have rendered the first and last axis labels alone using this axisLabelFormatter callback, and its invoked while rendering each axis label in the chart. Please refer the following code snippet.
Code snippet :
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Syncusion flutter charts'),
centerTitle: true,
),
body: SfCartesianChart(
primaryXAxis: CategoryAxis(
axisLabelFormatter: (AxisLabelRenderDetails details) {
String text = details.value == 0
? 'Jun 2022'
: details.value == chartData.length - 1
? 'Mar 2022'
: "";
return ChartAxisLabel(text, details.textStyle);
},
majorGridLines: const MajorGridLines(width: 0),
majorTickLines: const MajorTickLines(width: 0),
),
primaryYAxis: NumericAxis(
isVisible: false,
majorTickLines: const MajorTickLines(width: 0),
majorGridLines: const MajorGridLines(width: 0),
),
series: <ChartSeries<ChartSampleData, String>>[
ColumnSeries<ChartSampleData, String>(
dataSource: chartData,
dataLabelSettings: const DataLabelSettings(isVisible: true),
xValueMapper: (ChartSampleData sales, _) => sales.x,
yValueMapper: (ChartSampleData sales, _) => sales.y),
],
),
),
);
}
}
class ChartSampleData {
ChartSampleData(this.x, this.y);
final String? x;
final double? y;
}
final List<ChartSampleData> chartData = [
ChartSampleData('jan', 50.56),
ChartSampleData('Feb', 49.42),
ChartSampleData('Mar', 53.21),
ChartSampleData('Apr', 64.78),
ChartSampleData('May', 59.97),
];
ScreenShot:
Syncfusion Custom Axis Label
Regards,
Lokesh Palani.
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 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;
}
}
how to flutter syncfusion bar chart background grid line delete?
use pub.dev // syncfusion_flutter_charts 19.4.56
https://pub.dev/packages/syncfusion_flutter_charts
< image grid line (grey color line) >
my code
return SfCartesianChart(
title: ChartTitle(text: totalTaxString, textStyle: const TextStyle(fontWeight: FontWeight.bold)),
primaryXAxis: CategoryAxis(
maximumLabelWidth: MediaQuery.of(context).size.width > 480 ? MediaQuery.of(context).size.width * 0.3 : 100,
labelStyle: const TextStyle(overflow: TextOverflow.ellipsis)
// isVisible: false
),
primaryYAxis: CategoryAxis(
isVisible: false
),
series: <BarSeries>[
BarSeries<ModelPioChartData, String>(
dataSource: listPioChartData,
pointColorMapper:(ModelPioChartData data, _) => data.color,
xValueMapper: (ModelPioChartData data, _) => data.x,
yValueMapper: (ModelPioChartData data, _) => data.y,
dataLabelMapper: (ModelPioChartData data, _) {
if(data.y.toStringAsFixed(0).length > 4) {
return "${data.y/10000}์กฐ ์";
} else {
return "${data.y.toStringAsFixed(0)}์ต ์";
}
},
dataLabelSettings: const DataLabelSettings(
isVisible: true
),
enableTooltip: true,
),
],
);
I suggest you use the majorGridLines property in the axis, you can customize the width, color, and size of the major grid line. We have attached the code snippet and UG below for your reference.
primaryXAxis:
CategoryAxis(
majorGridLines: const MajorGridLines(width: 0)
),
UG: https://help.syncfusion.com/flutter/cartesian-charts/axis-customization#grid-lines-customization