How to override series level markerSettings from SfCartesianChart()? - flutter

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;
}
}

Related

Using sync fusion for live charts in flutter, I set up a marker, and after the graph updates once it just disappears

Marker disappears after the live chart updates once
I tried 3 main ways.
The first one was using setState, that did not work.
The second one was using updateDataSource, took inspiration from https://github.com/SyncfusionExamples/how-to-create-a-real-time-flutter-chart-in-10-minutes/blob/main/lib/main.dart, but it seems that the graph doesnt appear for me in this technique.
Lastly, the only thing that actually shows the graph for me is using stream builder, but with stream builder the marker only appears for a split second before the graph updates.
keep in mind i couldnt copy paste this code, it was on a different computer not connected to the internet, thus I had to type it on my own, so there might be small typos here and there.
class _GraphState extends State<Graph>{
#override
Widget build(BuildContext context{
final pointsProvider = Provider.of(PointsProvider>(context);
Stream<List<Point>> stream() async*{
while (true){
await Future<void>delayed(Duration(miliseconds: 200));
await pointsProvider.fetchPoints();
yield pointsProvider.points as List<Point>;
}
}
return StreamBuilder(
stream: stream(),
builder: (context, snapshot){
return Container(
margin: EdgeInsets.symmetric(horizontal: 40),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7)),
width: 960
height: 360,
child: SfCartesianChart(
onMarkerRender: (args){
if (args.pointsIndex! != 50){
args.markerHeight = 0;
args.markerWidth = 0;
}
},
plotAreaBackgroundColor: Color.fromRGBO(46, 46, 46, 1),
series: <ChartSeries>[
LineSeries<Point, double>(
markerSettings: MarkerSettings(
isVisible: true,
height: 40,
color: Colors.black,
width: 20,
),
color: Colors.yellow,
dataSource:
pointsProvider.points as List<Point>,
xValueMapper: (Point data, _) => point.x,
yValueMapper: (Point data, _) => point.y,
),
],
),
);
},
);
}
}

Extra spacing around SfCircularChart

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.

Why Firebase .onValue not working properly

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,
)
],
),

Create a customised bar graph using SfCartesianChart

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.

Flutter Charts - marker color not matching series color

I am using TimeSeriesChart from the flutter_charts package, and the colors of the selected markers are not matching up with their corresponding line color. There is also no data from other series hiding behind these data points.
Since the series is dynamic, I am setting to colorFn using math.Random to generate random colors for each series.
Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0))
I'm not sure how this would affect the markers, though, since the series is compiled before the markers are used. Here is the function I'm using to build my series, along with the chart
List<charts.Series<ResultSummary, DateTime>> _createChartData() {
// create chart map
Map<String, List<ResultSummary>> chartMap = {};
ConsumerTargetResults selectedTargetResults = getConsumerTargetResults(resultsPool, [selectedTarget])[0];
Map<String, Color> promptColorMap = {};
promptColorMap['Independent'] = Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
promptColorMap.addAll(Map.fromIterable(selectedTargetResults.target.prompts, key: (p) =>
p.title, value: (p) => Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0))
);
promptColorMap.forEach((key, value) {
List<ResultSummary> resultSummaries = [];
for (Session s in selectedTargetResults.sessions) {
ResultSummary tResultSummary = ResultSummary(s.date, 0, value);
if (s.promptStatsMap[key] != null) tResultSummary.measure = s.promptStatsMap[key];
resultSummaries.add(tResultSummary);
}
chartMap[key] = resultSummaries;
});
// implement to chart
List<charts.Series<ResultSummary, DateTime>> chartDataList = [];
chartMap.forEach((key, value) {
chartDataList.add(
charts.Series<ResultSummary, DateTime>(
id: key,
data: value,
domainFn: (ResultSummary r, _) => r.domain,
measureFn: (ResultSummary r, _) => r.measure,
fillColorFn: (ResultSummary r, _) => r.color,
));
});
return chartDataList;
}
Expanded(
child: Container(
padding: EdgeInsets.fromLTRB(40.0, 10.0, 40.0, 10.0),
child: charts.TimeSeriesChart(
widget.seriesList,
// animate: widget.animate,
animate: false,
behaviors: [ charts.SeriesLegend(
position: charts.BehaviorPosition.end,
outsideJustification: charts.OutsideJustification.endDrawArea,
horizontalFirst: false,
desiredMaxColumns: 1,
cellPadding: EdgeInsets.only(right: 4.0, bottom: 4.0),
entryTextStyle: charts.TextStyleSpec(
color: charts.MaterialPalette.purple.shadeDefault,
fontFamily: 'Georgia',
fontSize: 11),
)],
selectionModels: [
charts.SelectionModelConfig(
type: charts.SelectionModelType.info,
changedListener: _onSelectionChanged,
updatedListener: _onSelectionChanged,
)
],
)),
),
I removed the colorFn field from my chart and that seemed to have done the trick
// implement to chart series
List<charts.Series<ResultSummary, DateTime>> chartDataList = [];
chartMap.forEach((key, value) {
chartDataList.add(
charts.Series<ResultSummary, DateTime>(
id: key,
data: value,
domainFn: (ResultSummary r, _) => r.domain,
measureFn: (ResultSummary r, _) => r.measure,
// fillColorFn: (ResultSummary r, _) => r.color,
));
});