Closed KrohnMi closed 2 months ago
Hi @KrohnMi,
We have analyzed your query and can reproduce the reported issue. This is because using the same rangeController for multiple charts leads to state updates during the build process, causing synchronization problems. To resolve this issue, we recommend using separate rangeController instances for each chart.
We have modified your code snippet to achieve multiple chart synchronization with a single slider by using two rangeController instances, rangeController1 and rangeController2. Each controller manages the visible data range for its respective chart. We've added listeners to these controllers so that when one chart's range changes, the other chart updates accordingly. Additionally, to prevent state updates during the build process, we utilize an addPostFrameCallback. This callback ensures that updates to the controllers occur after the current frame is rendered and ensures smooth synchronization between the charts and the range selector. We have shared a code snippet and a sample for your reference. You can modify the sample based on your needs.
Code snippet:
` late final double min;
late final double max;
late final RangeController rangeController1;
late final RangeController rangeController2;
@override
void initState() {
super.initState();
const int numOfElementsToShow = 10;
min = 2.0;
max = 19.0;
rangeController1 = RangeController(
start: min,
end: min + numOfElementsToShow,
);
rangeController2 = RangeController(
start: min,
end: min + numOfElementsToShow,
);
rangeController1.addListener(() {
SchedulerBinding.instance.addPostFrameCallback((_) {
rangeController2.start = rangeController1.start;
rangeController2.end = rangeController1.end;
});
});
rangeController2.addListener(() {
SchedulerBinding.instance.addPostFrameCallback((_) {
rangeController1.start = rangeController2.start;
rangeController1.end = rangeController2.end;
});
});
}
@override
void dispose() {
chartData.clear();
rangeController1.dispose();
rangeController2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final SfCartesianChart chart = SfCartesianChart(
enableAxisAnimation: false,
zoomPanBehavior: ZoomPanBehavior(
enablePanning: true,
zoomMode: ZoomMode.x,
enableMouseWheelZooming: true,
),
primaryXAxis: NumericAxis(
isVisible: false,
interval: 1,
minimum: min,
maximum: max,
rangeController: rangeController1,
),
primaryYAxis: const NumericAxis(
isVisible: true,
anchorRangeToVisiblePoints: false,
),
series: [
SplineSeries<ChartSampleData, double>(
dataLabelSettings: const DataLabelSettings(isVisible: true),
dataSource: chartData,
animationDuration: 0,
xValueMapper: (ChartSampleData sales, int index) => sales.x,
yValueMapper: (ChartSampleData sales, int index) => sales.y,
),
],
);
final SfCartesianChart chart2 = SfCartesianChart(
enableAxisAnimation: false,
zoomPanBehavior: ZoomPanBehavior(
enablePanning: true,
zoomMode: ZoomMode.x,
enableMouseWheelZooming: true,
),
primaryXAxis: NumericAxis(
isVisible: false,
interval: 1,
minimum: min,
maximum: max,
rangeController: rangeController2,
),
primaryYAxis: const NumericAxis(
isVisible: true,
anchorRangeToVisiblePoints: false,
),
series: [
SplineSeries<ChartSampleData, double>(
dataLabelSettings: const DataLabelSettings(isVisible: true),
dataSource: chartData,
animationDuration: 0,
xValueMapper: (ChartSampleData sales, int index) => sales.x,
yValueMapper: (ChartSampleData sales, int index) => sales.y,
),
],
);
return Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: chart,
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: chart2,
),
),
Container(
margin:
const EdgeInsets.only(left: 50, right: 10, top: 10, bottom: 20),
child: SfRangeSelectorTheme(
data: SfRangeSelectorThemeData(
thumbRadius: 0,
overlayRadius: 0,
inactiveTrackHeight: 0,
activeTrackHeight: 0,
inactiveRegionColor: Colors.black12.withOpacity(0.3),
activeRegionColor: Colors.black.withOpacity(0.7),
),
child: SfRangeSelector(
min: min,
max: max,
controller: rangeController1,
initialValues: SfRangeValues(
rangeController1.start,
rangeController1.end,
),
interval: 1,
dragMode: SliderDragMode.betweenThumbs,
child: SizedBox(
height: 5,
child: SfCartesianChart(
margin: const EdgeInsets.all(0),
primaryXAxis: const NumericAxis(isVisible: false),
primaryYAxis: const NumericAxis(isVisible: false),
series: [
SplineSeries<ChartSampleData, double>(
dataSource: chartData,
color: Colors.transparent,
xValueMapper: (ChartSampleData sales, int index) =>
sales.x,
yValueMapper: (ChartSampleData sales, int index) =>
sales.y,
),
],
` Please let us know if you need any further assistance.
Regards,
Preethika Selvam. gh1941.zip
Ok thanks this works
Bug description
I want a page with two charts. These three widgets should be controlled with one range slider. I think both charts should respond to the range slider and update accordingly.
But only one chart responds to the range slider. The second chart remains unchanged.
Steps to reproduce
Code sample
Code sample
```dart import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:syncfusion_flutter_core/core.dart'; import 'package:syncfusion_flutter_sliders/sliders.dart'; class Data { Data({required this.x, required this.y}); final double x; final double y; } class TwoChartsWidget extends StatefulWidget { const TwoChartsWidget({super.key}); @override StateStack Traces
Stack Traces
```dart #54 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1138:13) binding.dart:1138 #55 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:443:5) binding.dart:443 #56 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1392:15) binding.dart:1392 #57 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1313:9) binding.dart:1313 #58 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1171:5) binding.dart:1171 #59 _invoke (dart:ui/hooks.dart:312:13) hooks.dart:312 #60 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:419:5) platform_dispatcher.dart:419 #61 _drawFrame (dart:ui/hooks.dart:283:31) hooks.dart:283 The RangeController sending notification was: RangeController#ccae2 start: 7.997782186162624 end: 19.0 ════════════════════════════════════════════════════════════════════════════════ ```On which target platforms have you observed this bug?
iOS, macOS
Flutter Doctor output
Doctor output
```console Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-arm64, locale de-DE) [✗] Android toolchain - develop for Android devices ✗ Unable to locate Android SDK. Install Android Studio from: https://developer.android.com/studio/index.html On first launch it will assist you in installing the Android SDK components. (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). If the Android SDK has been installed to a custom location, please use `flutter config --android-sdk` to update to that location. [✓] Xcode - develop for iOS and macOS (Xcode 15.3) [✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable. [!] Android Studio (not installed) [✓] VS Code (version 1.88.1) [✓] Connected device (3 available) ! Error: Browsing on the local area network for iPad Celina. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac. The device must be opted into Developer Mode to connect wirelessly. (code -27) ! Error: Browsing on the local area network for iPad. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac. The device must be opted into Developer Mode to connect wirelessly. (code -27) [!] Network resources ✗ A network error occurred while checking "https://pub.dev/": Failed host lookup: 'pub.dev' ✗ A network error occurred while checking "https://storage.googleapis.com/": Failed host lookup: 'storage.googleapis.com' ✗ A network error occurred while checking "https://maven.google.com/": Failed host lookup: 'maven.google.com' ✗ A network error occurred while checking "https://cocoapods.org/": Failed host lookup: 'cocoapods.org' ✗ A network error occurred while checking "https://github.com/": Failed host lookup: 'github.com' ! Doctor found issues in 4 categories. ```