Related
I have been facing issues with displaying the tooltip for my line graph which is created from the FL charts package. On touching the line spots of the graph, my tooltip data is being duplicated and I have no idea why. Below attached is an example image and the code for my line chart.
LineChart(
LineChartData(
titlesData: FlTitlesData(
leftTitles: AxisTitles(),
rightTitles: AxisTitles(
sideTitles: SideTitles(
getTitlesWidget: getTitles,
reservedSize: 40,
showTitles: true,
),
),
topTitles: AxisTitles(),
bottomTitles: AxisTitles(),
),
gridData: FlGridData(
show: true,
drawVerticalLine: true,
drawHorizontalLine: true,
horizontalInterval: 4,
),
lineTouchData: LineTouchData(enabled: true),
maxY: 100,
lineBarsData: widget.weightLogData.map(
(d) {
List<FlSpot> weights = List.generate(
10,
(int index) {
return FlSpot(double.parse(index.toString()),
widget.weightLogData[index].weight!);
},
growable: false,
);
return LineChartBarData(
dotData: FlDotData(show: false),
spots: weights,
lineChartStepData: LineChartStepData(
stepDirection: 20,
),
);
},
).toList(),
),
),
Hello I want to create a chart like blazor chart in flutter i tried using the syncfusion package but that didn't been well for me or maybe i was doing something wrong because i was unable to scroll to the old chart data back through scrolling back and fourth.
Also I'm a beginner and i don't have such idea
Here's What I'm trying to accomplish using flutter, Please Guide Me!
I want To Create Something Like This
You can use the fl_chart package. It's highly configurable.
Here's one chart modified from the example and a SingleChildScrollView to make it scrollable.
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: const Color(0xff232d37),
),
home: const MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: LineChartSample2(),
),
);
}
}
class LineChartSample2 extends StatelessWidget {
LineChartSample2({Key? key}) : super(key: key);
final List<Color> gradientColors = [
Colors.white,
Colors.black38,
];
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: 2000,
height: 400,
child: Padding(
padding: const EdgeInsets.only(
right: 18.0, left: 12.0, top: 24, bottom: 12),
child: LineChart(
mainData(),
),
),
),
);
}
Widget bottomTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
color: Color(0xff68737d),
fontWeight: FontWeight.bold,
fontSize: 16,
);
Widget text = const Text('', style: style);
final step = data.length ~/ 4;
if (value.toInt() % step == 0) {
final index = value.toInt() ~/ step;
text = Text('0:${(index * 5).toString().padLeft(2, '0')}', style: style);
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 8.0,
child: text,
);
}
Widget leftTitleWidgets(double value, TitleMeta meta) {
const style = TextStyle(
color: Color(0xff67727d),
fontWeight: FontWeight.bold,
fontSize: 15,
);
String text = const {
1: '10K',
3: '30K',
5: '50K',
7: '70K',
9: '90K',
}[value.toInt()] ??
'';
return Text(text, style: style, textAlign: TextAlign.left);
}
LineChartData mainData() {
return LineChartData(
gridData: FlGridData(
show: false,
),
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 1,
getTitlesWidget: bottomTitleWidgets,
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 1,
getTitlesWidget: leftTitleWidgets,
reservedSize: 42,
),
),
),
borderData: FlBorderData(
show: false,
border: Border.all(color: const Color(0xff37434d), width: 1)),
minX: 0,
maxX: data.length - 1,
minY: 0,
maxY: 10,
lineBarsData: [
LineChartBarData(
spots: [
for (final entry in data.entries)
FlSpot(entry.key.toDouble(), entry.value.toDouble())
],
color: Colors.white,
barWidth: 2,
isStrokeCapRound: true,
dotData: FlDotData(
show: false,
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: gradientColors
.map((color) => color.withOpacity(0.3))
.toList(),
),
),
),
],
);
}
}
final data = [
3.45,
2.14,
1.88,
2.02,
2.25,
2.20,
2.18,
2.49,
2.87,
3.06,
3.00,
2.35,
2.08,
2.22,
2.24,
2.43,
2.14,
2.16,
2.16,
1.85,
2.02,
1.90,
2.12,
1.71,
1.85,
1.77,
1.79,
2.14,
2.25,
2.29,
2.31,
2.79,
2.54,
2.72,
2.37,
2.35,
2.41,
2.66,
2.79,
3.04,
3.58,
4.29,
3.99,
4.42,
5.05,
5.01,
5.51,
8.90,
8.16,
5.61,
5.23,
5.19,
4.19,
3.72,
3.10,
2.97,
2.18,
2.45,
2.33,
2.29,
2.31,
2.31,
3.02,
3.43,
3.50,
3.25,
2.99,
3.08,
3.54,
4.12,
4.04,
4.74,
5.42,
7.70,
5.92,
5.25,
5.80,
5.82,
5.03,
4.99,
4.62,
4.62,
4.46,
6.12,
6.13,
5.37,
5.38,
5.70,
6.33,
6.26,
5.92,
5.41,
5.15,
6.34,
6.16,
6.58,
6.15,
6.13,
6.95,
7.16,
6.46,
7.17,
7.62,
9.52,
1.75,
3.41,
0.30,
3.05,
8.68,
7.54,
6.88,
7.16,
6.25,
6.20,
6.16,
7.13,
4.90,
5.84,
7.41,
6.73,
6.54,
8,
7.11,
7.59,
7.63,
7.34,
6.21,
6.21,
6.08,
6.74,
7.09,
7.11,
7.99,
8.53,
9.41,
0.17,
1.26,
2.68,
1.08,
8.25,
7.66,
6.74,
6.67,
5.82,
5.24,
4.51,
3.95,
3.5,
3.83,
3.79,
3.37,
3.14,
2.99,
4.00,
3.66,
5.34,
5.83,
5.32,
4.29,
4.03,
4.13,
4.79,
4.62,
4.32,
3.89,
3.43,
3.70,
4.25,
4.49,
4.08,
3.97,
4.24,
4.30,
4.54,
4.41,
4.05,
3.89,
3.56,
3.24,
3.16,
2.66,
2.50,
2.16,
1.94,
2.43,
2.45,
2.95,
2.83,
2.85,
3.31,
3.54,
3.33,
3.33,
3.33,
3.81,
4.16,
4.04,
3.83,
3.62,
3.43,
3.62,
3.68,
3.64,
4.24,
4.70,
6,
4.90,
4.66,
4.58,
4.58,
4.04,
3.91,
3.91,
3.77,
4.12,
3.47,
2.99,
2.87,
2.83,
2.60,
2.85,
2.77,
2.83,
2.77,
2.66,
2.33,
2.08,
1.92,
2.27,
1.98,
1.72,
1.91,
1.91,
2.58,
2.81,
2.81,
2.99,
2.97,
2.54,
3.58,
3.29,
2.85,
2.87,
3.10,
3.14,
2.97,
2.97,
2.89,
2.97,
2.87,
3.00,
2.81,
3.87,
2.66,
2.68,
2.79,
2.79,
2.97,
2.83,
2.95,
3,
3.27,
4.08,
4.04,
3.10,
2.68,
2.95,
2.64,
2.64,
2.39,
2.37,
2.22,
2.56,
2.33,
2.64,
2.22,
2.02,
1.90,
1.79,
1.73,
1.75,
1.62,
1.77,
2.29,
].asMap();
You can scroll the chart in any direction by enabling the ZoomPanBehavior.enablePanning property. In addition, ZoomPanBehavior.zoomMode can be used to control the zooming and panning directions. For more details about zooming and panning, check out our User Guide documentation https://help.syncfusion.com/flutter/cartesian-charts/zoom-pan.
Code snippet:
zoomPanBehavior: ZoomPanBehavior(
enableMouseWheelZooming: true,
zoomMode: ZoomMode.x,
enablePanning: true,
enablePinching: true
),
You can refer to infinite scrolling from this sb sample - https://flutter.syncfusion.com/#/cartesian-charts/infinite-scrolling
How do I remove this weird trendline in flutter?
I think there might be a property I can put under the LineChart widget, but not sure what. During the initial startup, the charts don't show the trendline but after I long press on the ListTile, that's wrapped around it, the trendlines appear. Thanks in advance.
return SizedBox(
height: 30,
child: LineChart(LineChartData(
lineTouchData:
LineTouchData(enabled: false, handleBuiltInTouches: false),
minX: minMaxX['min'],
maxX: minMaxX['max'],
minY: minMaxY['min'],
maxY: minMaxY['max'],
titlesData: FlTitlesData(show: false),
gridData: FlGridData(
show: false, drawHorizontalLine: false, drawVerticalLine: false),
borderData: FlBorderData(show: false),
extraLinesData: ExtraLinesData(
extraLinesOnTop: false,
horizontalLines: [
HorizontalLine(y: widget.openPrice, color: kDisabledColor)
]),
lineBarsData: [
LineChartBarData(
isStepLineChart: false,
belowBarData: BarAreaData(
show: true,
colors: [chartColor.withOpacity(0.4)],
),
colors: [chartColor],
isCurved: false,
dotData: FlDotData(show: false),
spots: chartDataPoints
.map((point) => FlSpot(point['x'], point['y']))
.toList()),
])),
);
I want to update the data of my chart, but it doesn't work. I used the chart I saw on a YouTube Video, which is using the fl_chart package. This is the whole code of the Youtube Video: https://github.com/JohannesMilke/fl_bar_chart_example. I think I have to use a setState somewhere, but I don't know where... I tried some options, but all failed, so I saw no other way than asking you. The weekChartDataGlobal is the varaiable which I want to be able to change, so my goal is to make the chart dynamic. I just putted you more or less the whole code into the question, because I don't know exactly what you need in order to answer my question. If you need more code please write me. Thanks in advance for helping me out with this big, big question.
class BarChartWidget extends StatefulWidget {
#override
_BarChartWidgetState createState() => _BarChartWidgetState();
}
class _BarChartWidgetState extends State<BarChartWidget> {
final double barWidth = 22;
#override
Widget build(BuildContext context) {
return BarChart(
BarChartData(
alignment: BarChartAlignment.center,
maxY: 20,
minY: 0,
groupsSpace: MediaQuery.of(context).size.width * 0.05,
barTouchData: BarTouchData(enabled: true),
titlesData: FlTitlesData(
bottomTitles: BarTitles.getTopBottomTitles(),
leftTitles: BarTitles.getSideTitles(),
),
gridData: FlGridData(
checkToShowHorizontalLine: (value) => value % BarData.interval == 0,
getDrawingHorizontalLine: (value) {
if (value == 0) {
return FlLine(
color: const Color(0xff363753),
strokeWidth: 3,
);
} else {
return FlLine(
color: const Color(0xff2a2747),
strokeWidth: 0.8,
);
}
},
),
barGroups: BarData.barData
.map(
(data) => BarChartGroupData(
x: data.id,
barRods: [
BarChartRodData(
y: data.y,
width: barWidth,
colors: [data.color],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
)),
],
),
)
.toList(),
),
);
}
}
class BarTitles {
static SideTitles getTopBottomTitles() => SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: Colors.white, fontSize: 12),
margin: 0,
getTitles: (double id) => BarData.barData
.firstWhere((element) => element.id == id.toInt())
.name,
);
static SideTitles getSideTitles() => SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: Colors.white, fontSize: 12),
rotateAngle: 90,
interval: BarData.interval.toDouble(),
margin: 0,
reservedSize: 30,
getTitles: (double value) => value == 0 ? '0' : '${value.toInt()}',
);
}
class BarData {
static int interval = 5;
static List<Data> barData = [
Data(
id: 0,
name: 'Mon',
y: weekChartDataGlobal[0]['dayTime'].toDouble(),
color: Color(0xff19bfff),
),
Data(
name: 'Tue',
id: 1,
y: weekChartDataGlobal[1]['dayTime'].toDouble(),
color: Color(0xffff4d94),
),
Data(
name: 'Wed',
id: 2,
y: weekChartDataGlobal[2]['dayTime'].toDouble(),
color: Color(0xff2bdb90),
),
Data(
name: 'Thu',
id: 3,
y: weekChartDataGlobal[3]['dayTime'].toDouble(),
color: Color(0xffffdd80),
),
Data(
name: 'Fri',
id: 4,
y: weekChartDataGlobal[4]['dayTime'].toDouble(),
color: Color(0xff2bdb90),
),
Data(
name: 'Sat',
id: 5,
y: weekChartDataGlobal[5]['dayTime'].toDouble(),
color: Color(0xffffdd80),
),
Data(
name: 'Sun',
id: 6,
y: weekChartDataGlobal[6]['dayTime'].toDouble(),
color: Color(0xffff4d94),
),
];
}
class Data {
// for ordering in the graph
final int id;
final String name;
final double y;
final Color color;
const Data({
#required this.name,
#required this.id,
#required this.y,
#required this.color,
});
}
Well the only way I got to update this chart is to put the chart inside a list variable, put this list inside the build method and replace the chart using a function everytime I want to update the chart. Let me try to explain it. Follow the steps in order to understand what i'm doing here and be patient. To test it right away just copy the code, delete my comments and run it. Don't forget to use pub get for fl_chart dependencies in pubspec.yaml and importing the library with the import 'package:fl_chart/fl_chart.dart';
// STEP 1 - create the global variables - this is to adapt your code to this approach.
//Put all these variables outside and above any function of your BarChartWidget class.
late BuildContext sameContext; //we will initialize this variable later, its the build's method context variable
late _BarChartWidgetState thisState; //we will initialize this variable later, its the class State variable, wich contains the setState method
double theChanges = 0; // this is a placeholder for your weekChartDataGlobal variable since i don't know what is this weekChartDataGlobal but i know its the info that will be displayed and updated in the Y axis of the chart so i replaced it with this double variable to ilustrate this approach
final double barWidth = 22; // your barWidth variable made global
// STEP 4 - here is the method to get a new chart. It's the exact same code of our theChart list
//but once we throw the old BarChart widget away we need to get another and this new one will call all
//its methods again and be updated with the new Y values from theChanges in new Data objects.
//So this method just return the BarChart widget.
Widget getTheChart(){
return BarChart(
BarChartData(
alignment: BarChartAlignment.center,
maxY: 20,
minY: 0,
groupsSpace: MediaQuery.of(sameContext).size.width * 0.05,
barTouchData: BarTouchData(enabled: true),
titlesData: FlTitlesData(
bottomTitles: BarTitles.getTopBottomTitles(),
leftTitles: BarTitles.getSideTitles(),
),
gridData: FlGridData(
checkToShowHorizontalLine: (value) => value % BarData.interval == 0,
getDrawingHorizontalLine: (value) {
if (value == 0) {
return FlLine(
color: const Color(0xff363753),
strokeWidth: 3,
);
} else {
return FlLine(
color: const Color(0xff2a2747),
strokeWidth: 0.8,
);
}
},
),
barGroups: BarData.barData
.map(
(data) => BarChartGroupData(
x: data.id,
barRods: [
BarChartRodData(
y: data.y,
width: barWidth,
colors: [data.color],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
)),
],
),
).toList(),
),
);
}
// STEP 2 - Here i putted all the widgets of your page inside a list variable called theChart,
//this is to make things easier to control, so we can update the BarChart widget easily.
//In this list i'm putting your BarChart widget and a Button widget below it for you to be able to see
//the chart being updated. I created this list too as a global variable.
//Note that since this list is being declared outside the build method, we are using
//sameContext variable instead of context and thisState.setState((){}) instead of setState((){}).
//As you can see in the list, the BarChart widget is placed at 0 and the Container holding the
//MaterialButton is placed at 1.
List<Widget> theChart = <Widget>[
BarChart(
BarChartData(
alignment: BarChartAlignment.center,
maxY: 20,
minY: 0,
//sameContext variable being used here
groupsSpace: MediaQuery.of(sameContext).size.width * 0.05,
barTouchData: BarTouchData(enabled: true),
titlesData: FlTitlesData(
bottomTitles: BarTitles.getTopBottomTitles(),
leftTitles: BarTitles.getSideTitles(),
),
gridData: FlGridData(
checkToShowHorizontalLine: (value) => value % BarData.interval == 0,
getDrawingHorizontalLine: (value) {
if (value == 0) {
return FlLine(
color: const Color(0xff363753),
strokeWidth: 3,
);
} else {
return FlLine(
color: const Color(0xff2a2747),
strokeWidth: 0.8,
);
}
},
),
barGroups: BarData.barData
.map(
(data) => BarChartGroupData(
x: data.id,
barRods: [
BarChartRodData(
y: data.y,
width: barWidth,
colors: [data.color],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
)),
],
),
).toList(),
),
),
//this is the button widget, click to increase Y (theChanges variable) by 5,
//long press to decrease Y (theChanges variable) by 5
Container(
margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: MaterialButton(
color: Colors.lightBlue,
textColor: Colors.white,
child: Text("Press me!"),
onPressed: () {
//when you press the button we enter this method. Here we are outside the build method wich contains
//the context and the state variables so we need to use our state variable to call the setState
//method. This is the key point of the whole thing of updating the chart. We change the variable
//holding the Y value in the chart, here i'm using my theChanges variable but in your code it's that weekChartDataGlobal.
//Then we call the function BarData.updateData() (check step 3) to update the BarData static list variable wich contains the actual
//objects holding the Y values in the chart, and then we REPLACE THE BarChart WIDGET. That's right we throw
//the old widget away and replace it with a new one with the new values. Widgets atributes are final, we
//can't change them once they're settled so we need to replace them, the sooner you accept it the sooner you'll understand all this.
thisState.setState((){
theChanges += 5;
BarData.updateData();
theChart.removeAt(0);
theChart.insert(0, getTheChart()); // check step 4
});
},
onLongPress: (){
thisState.setState((){
theChanges -= 5;
BarData.updateData();
theChart.removeAt(0);
theChart.insert(0, getTheChart());
});
},
),
),
].toList();
class BarChartWidget extends StatefulWidget {
#override
_BarChartWidgetState createState() => _BarChartWidgetState();
}
class _BarChartWidgetState extends State<BarChartWidget> {
#override
Widget build(BuildContext context) {
// at this method your page will actually be built, here is where all the action will happen
//indeed so we
sameContext = context; // initialize our global context variable
thisState = this; // initialize our global State variable
//here we put theChart list variable inside a ListView and the ListView inside a container.
//The build method will get each widget inside the list and place it in order
return Container(
child: ListView.builder(
itemCount: theChart.length,
itemBuilder: (context, index){
return theChart[index];
},
),
);
}
}
class BarTitles {
static SideTitles getTopBottomTitles() => SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: Colors.white, fontSize: 12),
margin: 0,
getTitles: (double id) => BarData.barData
.firstWhere((element) => element.id == id.toInt())
.name,
);
static SideTitles getSideTitles() => SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: Colors.white, fontSize: 12),
rotateAngle: 90,
interval: BarData.interval.toDouble(),
margin: 0,
reservedSize: 30,
getTitles: (double value) => value == 0 ? '0' : '${value.toInt()}',
);
}
// STEP 3 here i replaced your weekChartDataGlobal with my theChanges variable to ilustrate the
//update and created the updateData() method.
class BarData {
static int interval = 5;
static List<Data> barData = [
Data(
id: 0,
name: 'Mon',
//y: weekChartDataGlobal[0]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff19bfff),
),
Data(
name: 'Tue',
id: 1,
//y: weekChartDataGlobal[1]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffff4d94),
),
Data(
name: 'Wed',
id: 2,
//y: weekChartDataGlobal[2]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff2bdb90),
),
Data(
name: 'Thu',
id: 3,
//y: weekChartDataGlobal[3]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffffdd80),
),
Data(
name: 'Fri',
id: 4,
//y: weekChartDataGlobal[4]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff2bdb90),
),
Data(
name: 'Sat',
id: 5,
//y: weekChartDataGlobal[5]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffffdd80),
),
Data(
name: 'Sun',
id: 6,
//y: weekChartDataGlobal[6]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffff4d94),
),
];
//this is another key point. Note that here i'm just clearing the whole static list and filling it
//again with the Data objects. I just copied the code above to create the static list and
//pasted down there. Why? Widgets attributes are final, their Y parameter won't change even if
//you update the theChanges variable so you need to throw them all away and place new ones
//with the new value of theChanges variable.
static void updateData(){
barData.clear();
barData = [
Data(
id: 0,
name: 'Mon',
//y: weekChartDataGlobal[0]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff19bfff),
),
Data(
name: 'Tue',
id: 1,
//y: weekChartDataGlobal[1]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffff4d94),
),
Data(
name: 'Wed',
id: 2,
//y: weekChartDataGlobal[2]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff2bdb90),
),
Data(
name: 'Thu',
id: 3,
//y: weekChartDataGlobal[3]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffffdd80),
),
Data(
name: 'Fri',
id: 4,
//y: weekChartDataGlobal[4]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xff2bdb90),
),
Data(
name: 'Sat',
id: 5,
//y: weekChartDataGlobal[5]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffffdd80),
),
Data(
name: 'Sun',
id: 6,
//y: weekChartDataGlobal[6]['dayTime'].toDouble(),
y: theChanges,
color: Color(0xffff4d94),
),
];
}
}
class Data {
// for ordering in the graph
final int id;
final String name;
final double y;
final Color color;
const Data({
required this.name,
required this.id,
required this.y,
required this.color,
});
}
In case anyone doesn't want to do such a complex workaround, I simply added a ValueKey to my graph constructor. Then attached this to my selector widget, which changes the timeframe my graph is showing, e.g. day, month, week.
e.g.
String _yourVariableThatChangesHere = "monthView";
GTBarChart(
key: ValueKey(_yourVariableThatChangesHere),
data: ...
)
Then when your _yourVariableThatChangesHere changes, the graph gets rebuilt when you call setState.
I'm implementing line chart in flutter i have draw the line chart but i need to show horizontal lines in different colors. Is there any way to get that?
Here is the attached image what i want to achieve.
LineChartData(
minX: 0,
maxX: 11,
minY: 0,
maxY: 6,
titlesData: LineTitles.getTitleData(),
gridData: FlGridData(
show: true,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 1,
);
},
drawVerticalLine: true,
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 1,
);
},
),
borderData: FlBorderData(
show: true,
border: Border.all(color: Colors.grey, width: 1),
),
lineBarsData: [
LineChartBarData(
spots: [
FlSpot(4.9, 5),
FlSpot(6.8, 2.5),
FlSpot(8, 4),
FlSpot(9.5, 3),
FlSpot(11, 4),
],
isCurved: true,
barWidth: 3,
),
],
),[![I need to show the orange and red horizontal lines][1]][1]
Yes you can check gridline colors in fl_chart. You've already used function with which you can modify these colors which is getDrawingHorizontalLine().
getDrawingHorizontalLine: (value) {
if(value == 1) {
return FlLine(
color: Colors.red,
strokeWidth: 2,
);
} else if (value == 2 ) {
return FlLine(
color: Colors.yellow,
strokeWidth: 2,
);
} else {
return FlLine(
color: Colors.grey,
strokeWidth: 2,
);
}
}
Now here as you can see I've added condition that if values are 1 or 2 then gridline colors should be red & yellow respectively. Now this is the ugly way to put condition to change color but you can do it dynamically yourself.
If you want to change vertical gridlines then you should use getDrawingVerticalLine() to change color values.
You can see my screenshot for output below.