Skip to content

Instantly share code, notes, and snippets.

@imaNNeo
Created September 14, 2023 23:47
Show Gist options
  • Save imaNNeo/946acd2c1718bec0c42e5cdede598868 to your computer and use it in GitHub Desktop.
Save imaNNeo/946acd2c1718bec0c42e5cdede598868 to your computer and use it in GitHub Desktop.
Multi synced line chart
import 'package:fl_chart/fl_chart.dart';
import 'package:fl_chart_app/presentation/resources/app_resources.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'presentation/router/app_router.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int? selectedIndex;
final dataSet1 = [0, 5, 3, 6, 7, 3, 0, 5, 3, 6, 7, 3, 0, 5, 3, 6, 7, 3, 0, 5];
final dataSet2 = [5, 3, 5, 2, 3, 1, 5, 3, 5, 2, 3, 1, 5, 3, 5, 2, 3, 1, 5, 3];
final dataSet3 = [3, 5, 3, 1, 3, 2, 3, 5, 3, 1, 3, 2, 3, 5, 3, 1, 3, 2, 3, 5];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
children: [
Expanded(
child: MyGenericChart(
title: 'Chart 1',
dataset: dataSet1,
selectedIndex: selectedIndex,
onSelectedIndexChanged: _onSelectedIndexChanged,
color: Colors.redAccent,
),
),
Expanded(
child: MyGenericChart(
title: 'Chart 2',
dataset: dataSet2,
selectedIndex: selectedIndex,
onSelectedIndexChanged: _onSelectedIndexChanged,
color: Colors.green,
),
),
Expanded(
child: MyGenericChart(
title: 'Chart 3',
dataset: dataSet3,
selectedIndex: selectedIndex,
onSelectedIndexChanged: _onSelectedIndexChanged,
color: Colors.blueAccent,
),
),
],
),
),
);
}
void _onSelectedIndexChanged(int? newSelectedIndex) {
setState(() {
selectedIndex = newSelectedIndex;
});
}
}
class MyGenericChart extends StatelessWidget {
const MyGenericChart({
super.key,
required this.title,
required this.dataset,
required this.selectedIndex,
required this.onSelectedIndexChanged,
required this.color,
});
final String title;
final List<int> dataset;
final int? selectedIndex;
final ValueChanged<int?> onSelectedIndexChanged;
final Color color;
static const _minY = 0.0;
static const _maxY = 8.0;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: const TextStyle(fontSize: 24)),
const SizedBox(height: 8),
Expanded(
child: LineChart(
LineChartData(
minY: _minY,
maxY: _maxY,
lineBarsData: [
LineChartBarData(
spots: dataset.asMap().entries.map(
(entry) {
return FlSpot(
entry.key.toDouble(),
// Index (zero to dataset.length - 1)
entry.value.toDouble(), // Value
);
},
).toList(),
showingIndicators:
selectedIndex == null ? [] : [selectedIndex!],
color: color,
),
],
lineTouchData: LineTouchData(
handleBuiltInTouches: false,
touchCallback:
(FlTouchEvent event, LineTouchResponse? res) {
if (event.isInterestedForInteractions &&
res != null &&
res.lineBarSpots != null &&
res.lineBarSpots!.isNotEmpty) {
final spot = res.lineBarSpots!.first;
final newSelectedIndex = spot.spotIndex;
onSelectedIndexChanged(newSelectedIndex);
} else {
onSelectedIndexChanged(null);
}
},
getTouchLineStart: (data, index) => _minY,
getTouchLineEnd: (data, index) => _maxY,
),
titlesData: const FlTitlesData(show: false)),
),
),
],
),
);
}
}
@imaNNeo
Copy link
Author

imaNNeo commented Sep 14, 2023

multi-synced-line-chart2.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment