import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class Chart extends StatefulWidget {
const Chart({Key? key}) : super(key: key);
@override
_chartState createState() => _chartState();
}
class _chartState extends State<Chart> {
int? x = 10;
int? y = 15;
Timer? timer;
int index = 0;
@override
void dispose() {
timer!.cancel();
super.dispose();
}
TooltipBehavior? _tooltipBehavior;
List<Widget> stackList = [];
ChartSeriesController? _controller;
late TrackballBehavior _trackballBehavior;
late CrosshairBehavior _crosshairBehavior;
@override
void initState() {
super.initState();
_trackballBehavior = trackballBehavior();
// _tooltipBehavior = tooltipBehavior();
_crosshairBehavior = crosshairBehavior();
timer = Timer.periodic(const Duration(seconds: 3), (_timer) {
updateData().then((value) {
print(index);
pri
_trackballBehavior.show(
chartCustomData[index].x,
chartCustomData[index].y!.toDouble(),
);
_crosshairBehavior.show(
chartCustomData[index].x,
chartCustomData[index].y!.toDouble(),
);
});
// if (_crosshairBehavior != null) {
// _crosshairBehavior.showByIndex(index);
// }
});
}
CrosshairBehavior crosshairBehavior() {
return CrosshairBehavior(
activationMode: ActivationMode.singleTap,
enable: true,
shouldAlwaysShow: true,
lineType: CrosshairLineType.horizontal,
);
}
TooltipBehavior tooltipBehavior() {
return TooltipBehavior(
canShowMarker: true,
animationDuration: 0,
activationMode: ActivationMode.singleTap,
shouldAlwaysShow: true,
elevation: 6,
duration: 1,
format: 'tool tip header',
tooltipPosition: TooltipPosition.auto,
color: Colors.indigoAccent,
enable: true,
builder: (data, point, series, pointIndex, seriesIndex) {
print(
'---- tool tip ${data}, ${point}, ${series}, ${pointIndex}, ${seriesIndex}');
return Card(
child: Text('Data${chartCustomData[pointIndex].y}'),
);
},
);
}
TrackballBehavior trackballBehavior() {
return TrackballBehavior(
enable: true,
lineColor: Colors.cyan,
// shouldAlwaysShow: true,
activationMode: ActivationMode.singleTap,
lineType: TrackballLineType.horizontal,
hideDelay: 10,
shouldAlwaysShow: true,
tooltipDisplayMode: TrackballDisplayMode.groupAllPoints,
// lineDashArray: const [1.7],
// tooltipDisplayMode: TrackballDisplayMode.floatAllPoints,
// tooltipAlignment: ChartAlignment.near,
// lineWidth: 2,
// tooltipSettings: const InteractiveTooltip(
// enable: true,
// color: Colors.cyan,
// ),
// builder: (context, trackballDetails) {
// // print(trackballDetails.point!.currentPoint);
// latLong.add(
// Position(
// x: trackballDetails.point!.x.toDouble(),
// y: trackballDetails.point!.y.toDouble(),
// ),
// );
// return Card(
// color: Colors.white,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(
// 16,
// ),
// ),
// child: Padding(
// padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4),
// child: Text(
// 'x ${trackballDetails.point!.x.toDouble()}\n y ${trackballDetails.point!.y.toDouble()}',
// ),
// ),
// );
// },
);
}
List<Position> latLong = [];
void onController(ChartSeriesController controller) {
_controller = controller;
}
@override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return WillPopScope(
onWillPop: () async {
timer!.cancel();
return true;
},
child: Scaffold(
body: SafeArea(
child: SizedBox(
height: height,
width: width,
child: SingleChildScrollView(
child: Column(
children: [
// Image.network(
// 'https://scraapynew.mrmmbs.com/public/en/uploaded_images/' +
// temp
// .replaceAll('\[', '')
// .replaceAll('\]', '')
// .replaceAll('\"', '')
// .replaceAll('\\', '')
// .split(',')
// .first,
// height: 30,
// width: 30,
// ),
SizedBox(
height: height / 2,
width: width,
child: Row(
children: [
Expanded(
child: SfCartesianChart(
title: ChartTitle(text: 'My Trade'),
trackballBehavior: _trackballBehavior,
// onMarkerRender: (markerArgs) {},
primaryXAxis: NumericAxis(
tickPosition: TickPosition.outside,
isVisible: true,
autoScrollingMode: AutoScrollingMode.start,
interactiveTooltip: const InteractiveTooltip(
enable: true,
canShowMarker: true,
),
),
crosshairBehavior: _crosshairBehavior,
// onTooltipRender: (TooltipArgs args) {
// args.text = 'Customized Text';
//
// print(
// '----- ${args.locationX} ${args.locationY}');
// },
series: <LineSeries<ChartSampleData, num>>[
LineSeries<ChartSampleData, num>(
animationDelay: 0,
isVisible: true,
/* markerSettings: const MarkerSettings(
isVisible: true,
shape: DataMarkerType.circle,
color: Colors.amber,
height: 5,
width: 5,
borderColor: Colors.orangeAccent,
),*/
animationDuration: 0,
enableTooltip: true, opacity: 1,
onRendererCreated: onController,
dataSource: chartCustomData,
xValueMapper: (ChartSampleData data, _) =>
data.x,
yValueMapper: (ChartSampleData data, _) =>
data.y,
// dataLabelSettings: DataLabelSettings(
// connectorLineSettings: ConnectorLineSettings(
// type: ConnectorType.curve,
// color: Colors.cyan,
// ),
// ),
),
],
),
),
SizedBox(
width: width / 5,
height: height / 2,
child: Stack(
children: [
...stackList,
],
),
)
],
),
),
ElevatedButton(
onPressed: () {
// updateData();
_trackballBehavior.show(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y!.toDouble(),
);
_crosshairBehavior.show(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y!.toDouble(),
);
// print('index $index');
var p = _controller!.pointToPixel(CartesianChartPoint(
chartCustomData[index - 1].x,
chartCustomData[index - 1].y));
print(p);
setState(() {
// _trackballBehavior!.showByIndex(index);
stackList.add(
Transform.translate(
offset: Offset(p.dx, p.dy),
child: SizedBox(
width: 200,
child: Row(
children: [
Column(
children: const [
CircleAvatar(
backgroundColor: Colors.cyan,
radius: 5,
),
Text('x'),
],
),
Divider(),
Column(
children: const [
CircleAvatar(
backgroundColor: Colors.cyan,
radius: 5,
),
Text('y'),
],
),
],
),
),
),
);
});
print(" ----- list ${stackList.length}");
},
child: const Text('put'),
),
],
),
)),
),
),
);
}
Future<List<ChartSampleData>> updateData() async {
if (mounted) {
setState(() {
y = Random().nextInt(150);
x = x! + 20;
chartCustomData.add(
ChartSampleData(
x: x,
y: y,
),
);
});
}
if (chartCustomData.length > 20) {
chartCustomData.removeAt(0);
_controller?.updateDataSource(
addedDataIndex: chartCustomData.length - 1,
removedDataIndex: 0,
);
} else {
_controller?.updateDataSource(
addedDataIndex: chartCustomData.length - 1,
);
}
index = chartCustomData.length - 1;
return chartCustomData;
}
List<ChartSampleData> chartCustomData = <ChartSampleData>[
ChartSampleData(x: 10, y: 15),
ChartSampleData(x: 20, y: 30),
ChartSampleData(x: 30, y: 45),
ChartSampleData(x: 40, y: 77),
];
final List<SalesData> chartData = <SalesData>[
SalesData(DateTime(2005, 0, 1), 'India', 1.5, 21, 28, 680, 760),
SalesData(DateTime(2006, 0, 1), 'China', 2.2, 24, 44, 550, 880),
SalesData(DateTime(2007, 0, 1), 'USA', 3.32, 36, 48, 440, 788),
SalesData(DateTime(2008, 0, 1), 'Japan', 4.56, 38, 50, 350, 560),
SalesData(DateTime(2009, 0, 1), 'Russia', 5.87, 54, 66, 444, 566),
SalesData(DateTime(2010, 0, 1), 'France', 6.8, 57, 78, 780, 650),
SalesData(DateTime(2011, 0, 1), 'Germany', 8.5, 70, 84, 450, 800)
];
List<LineSeries<SalesData, num>> getDefaultData() {
return <LineSeries<SalesData, num>>[
LineSeries<SalesData, num>(
// enableToolTip: isTooltipVisible,
dataSource: chartData,
xValueMapper: (SalesData sales, _) => sales.a1,
yValueMapper: (SalesData sales, _) => sales.a2,
width: 2,
// enableAnimation: false,
markerSettings: const MarkerSettings(
isVisible: true,
height: 4,
width: 4,
shape: DataMarkerType.circle,
borderWidth: 3,
borderColor: Colors.cyan,
),
dataLabelSettings: const DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.auto,
),
),
LineSeries<SalesData, num>(
enableTooltip: true,
dataSource: chartData,
// enableAnimation: false,
width: 2,
xValueMapper: (SalesData sales, _) => sales.a3,
yValueMapper: (SalesData sales, _) => sales.a4,
markerSettings: const MarkerSettings(
isVisible: true,
height: 4,
width: 4,
shape: DataMarkerType.circle,
borderWidth: 3,
borderColor: Colors.black),
dataLabelSettings: const DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.auto,
),
),
];
}
}
class SalesData {
DateTime? date;
String? text;
double? a;
int? a1, a2, a3, a4;
SalesData(
this.date,
this.text,
this.a,
this.a1,
this.a2,
this.a3,
this.a4,
);
}
class ChartSampleData {
int? x, y;
ChartSampleData({this.x, this.y});
}
class Position {
double? x, y;
Position({required this.x, required this.y});
}