- Created generated_plugin_registrant.cc and generated_plugin_registrant.h to manage plugin registration. - Added generated_plugins.cmake for plugin configuration in CMake. - Implemented CMakeLists.txt for the Windows runner, defining build settings and dependencies. - Created Runner.rc for application resources including versioning and icons. - Developed flutter_window.cpp and flutter_window.h to manage the Flutter window lifecycle. - Implemented main.cpp as the entry point for the Windows application. - Added resource.h for resource definitions. - Included app icon in resources. - Created runner.exe.manifest for application settings. - Developed utils.cpp and utils.h for console management and command line argument handling. - Implemented win32_window.cpp and win32_window.h for high DPI-aware window management.
410 lines
16 KiB
Dart
410 lines
16 KiB
Dart
import 'package:marco/controller/other/syncfusion_chart_controller.dart';
|
|
import 'package:marco/helpers/theme/app_theme.dart';
|
|
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
|
import 'package:marco/helpers/utils/my_shadow.dart';
|
|
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
|
|
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
|
|
import 'package:marco/helpers/widgets/my_card.dart';
|
|
import 'package:marco/helpers/widgets/my_flex.dart';
|
|
import 'package:marco/helpers/widgets/my_flex_item.dart';
|
|
import 'package:marco/helpers/widgets/my_spacing.dart';
|
|
import 'package:marco/helpers/widgets/my_text.dart';
|
|
import 'package:marco/model/chart_model.dart';
|
|
import 'package:marco/view/layouts/layout.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
|
|
|
class SyncFusionChartScreen extends StatefulWidget {
|
|
const SyncFusionChartScreen({super.key});
|
|
|
|
@override
|
|
State<SyncFusionChartScreen> createState() => _SyncFusionChartScreenState();
|
|
}
|
|
|
|
class _SyncFusionChartScreenState extends State<SyncFusionChartScreen> with SingleTickerProviderStateMixin, UIMixin {
|
|
late SyncfusionChartController controller;
|
|
|
|
@override
|
|
void initState() {
|
|
controller = SyncfusionChartController();
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Layout(
|
|
child: GetBuilder(
|
|
init: controller,
|
|
builder: (controller) {
|
|
return Column(
|
|
children: [
|
|
Padding(
|
|
padding: MySpacing.x(flexSpacing),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
MyText.titleMedium("Other", fontSize: 18, fontWeight: 600),
|
|
MyBreadcrumb(
|
|
children: [MyBreadcrumbItem(name: 'Other'), MyBreadcrumbItem(name: 'Syncfusion Chart', active: true)],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
MySpacing.height(flexSpacing),
|
|
Padding(
|
|
padding: MySpacing.x(flexSpacing / 2),
|
|
child: MyFlex(
|
|
children: [
|
|
MyFlexItem(sizes: 'lg-6', child: _buildDefaultLineChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildCustomizedColumnChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildDashedSplineChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildAreaZoneChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildDefaultBarChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildMultipleSeriesBubbleChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildShapesScatterChart()),
|
|
MyFlexItem(sizes: 'lg-6', child: _buildDashedStepLineChart()),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDashedStepLineChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'CO2 - Intensity analysis'),
|
|
primaryXAxis: NumericAxis(
|
|
interval: 1,
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
title: AxisTitle(text: 'Year'),
|
|
),
|
|
primaryYAxis: NumericAxis(
|
|
axisLine: AxisLine(width: 0),
|
|
minimum: 360,
|
|
maximum: 600,
|
|
interval: 30,
|
|
majorTickLines: MajorTickLines(size: 0),
|
|
title: AxisTitle(text: 'Intensity (g/kWh)'),
|
|
),
|
|
legend: Legend(isVisible: true, position: LegendPosition.bottom),
|
|
tooltipBehavior: TooltipBehavior(enable: true),
|
|
series: controller.getDashedStepLineSeries(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildShapesScatterChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'Inflation Analysis'),
|
|
primaryXAxis: NumericAxis(
|
|
minimum: 1945,
|
|
maximum: 2005,
|
|
title: AxisTitle(text: 'Year'),
|
|
labelIntersectAction: AxisLabelIntersectAction.multipleRows,
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
),
|
|
legend: Legend(isVisible: true, position: LegendPosition.bottom),
|
|
primaryYAxis: NumericAxis(
|
|
title: AxisTitle(text: 'Inflation Rate(%)'), labelFormat: '{value}%', axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(size: 0)),
|
|
tooltipBehavior: controller.scatterTooltipBehavior,
|
|
series: controller.getScatterShapesSeries(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDefaultLineChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'Inflation - Consumer price'),
|
|
legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap, position: LegendPosition.bottom),
|
|
primaryXAxis: NumericAxis(edgeLabelPlacement: EdgeLabelPlacement.shift, interval: 2, majorGridLines: MajorGridLines(width: 0)),
|
|
primaryYAxis: NumericAxis(labelFormat: '{value}%', axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(color: Colors.transparent)),
|
|
series: controller.getDefaultLineSeries(),
|
|
tooltipBehavior: TooltipBehavior(enable: true),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildCustomizedColumnChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
title: ChartTitle(text: 'PC vendor shipments - 2015 Q1'),
|
|
primaryXAxis: CategoryAxis(
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
),
|
|
primaryYAxis: NumericAxis(
|
|
labelFormat: '{value}M',
|
|
title: AxisTitle(text: 'Shipments in million'),
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
majorTickLines: MajorTickLines(size: 0)),
|
|
series: <CartesianSeries<ChartSampleData, String>>[
|
|
ColumnSeries<ChartSampleData, String>(
|
|
onCreateRenderer: (ChartSeries<ChartSampleData, String> series) {
|
|
return _CustomColumnSeriesRenderer(ThemeData.light());
|
|
},
|
|
dataLabelSettings: DataLabelSettings(isVisible: true, labelAlignment: ChartDataLabelAlignment.middle),
|
|
dataSource: <ChartSampleData>[
|
|
ChartSampleData(x: 'HP Inc', y: 12.54, pointColor: Color.fromARGB(53, 92, 125, 1)),
|
|
ChartSampleData(x: 'Lenovo', y: 13.46, pointColor: Color.fromARGB(192, 108, 132, 1)),
|
|
ChartSampleData(x: 'Dell', y: 9.18, pointColor: Color.fromARGB(246, 114, 128, 1)),
|
|
ChartSampleData(x: 'Apple', y: 4.56, pointColor: Color.fromARGB(248, 177, 149, 1)),
|
|
ChartSampleData(x: 'Asus', y: 5.29, pointColor: Color.fromARGB(116, 180, 155, 1)),
|
|
],
|
|
width: 0.8,
|
|
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
|
|
yValueMapper: (ChartSampleData sales, _) => sales.y,
|
|
pointColorMapper: (ChartSampleData sales, _) => sales.pointColor,
|
|
)
|
|
],
|
|
tooltipBehavior: controller.tooltipBehavior,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDashedSplineChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'Total investment (% of GDP)'),
|
|
legend: Legend(isVisible: true, position: LegendPosition.bottom),
|
|
primaryXAxis: NumericAxis(
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
interval: 1,
|
|
),
|
|
primaryYAxis: NumericAxis(
|
|
minimum: 16,
|
|
maximum: 28,
|
|
interval: 4,
|
|
labelFormat: '{value}%',
|
|
axisLine: AxisLine(width: 0),
|
|
),
|
|
series: controller.getDashedSplineSeries(),
|
|
tooltipBehavior: TooltipBehavior(enable: true),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildAreaZoneChart() {
|
|
final Orientation orientation = MediaQuery.of(context).orientation;
|
|
final double containerSize = kIsWeb
|
|
? 80
|
|
: orientation == Orientation.portrait
|
|
? 80
|
|
: 45;
|
|
final double fontSize = 14 / MediaQuery.of(context).textScaler.scale(1);
|
|
final double size = 13 / MediaQuery.of(context).textScaler.scale(1);
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
legend: Legend(position: LegendPosition.bottom),
|
|
title: ChartTitle(text: 'Average monthly temperature of US - 2020'),
|
|
primaryXAxis: CategoryAxis(majorGridLines: MajorGridLines(width: 0)),
|
|
primaryYAxis:
|
|
NumericAxis(labelFormat: '{value}°F', minimum: 0, maximum: 90, interval: 30, axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(size: 0)),
|
|
series: controller.getAreaZoneSeries(),
|
|
tooltipBehavior: controller.areaTooltipBehavior,
|
|
annotations: <CartesianChartAnnotation>[
|
|
CartesianChartAnnotation(
|
|
widget: SizedBox(
|
|
height: containerSize,
|
|
width: containerSize,
|
|
child: Column(
|
|
children: <Widget>[
|
|
Row(children: <Widget>[
|
|
Icon(
|
|
Icons.circle,
|
|
color: Color.fromRGBO(116, 182, 194, 1),
|
|
size: size,
|
|
),
|
|
Text(
|
|
' Winter',
|
|
style: TextStyle(fontSize: fontSize),
|
|
),
|
|
]),
|
|
Row(children: <Widget>[
|
|
Icon(Icons.circle, color: Color.fromRGBO(75, 189, 138, 1), size: size),
|
|
Text(
|
|
' Spring',
|
|
style: TextStyle(fontSize: fontSize),
|
|
)
|
|
]),
|
|
Row(children: <Widget>[
|
|
Icon(Icons.circle, color: Color.fromRGBO(255, 186, 83, 1), size: size),
|
|
Text(
|
|
' Summer',
|
|
style: TextStyle(fontSize: fontSize),
|
|
)
|
|
]),
|
|
Row(children: <Widget>[
|
|
Icon(Icons.circle, color: Color.fromRGBO(194, 110, 21, 1), size: size),
|
|
Text(
|
|
' Autumn',
|
|
style: TextStyle(fontSize: fontSize),
|
|
)
|
|
]),
|
|
],
|
|
)),
|
|
coordinateUnit: CoordinateUnit.percentage,
|
|
x: kIsWeb ? '95%' : '85%',
|
|
y: kIsWeb ? '21%' : '14%')
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDefaultBarChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'Tourism - Number of arrivals'),
|
|
legend: Legend(isVisible: true, position: LegendPosition.bottom),
|
|
primaryXAxis: CategoryAxis(
|
|
majorGridLines: MajorGridLines(width: 0),
|
|
),
|
|
primaryYAxis: NumericAxis(majorGridLines: const MajorGridLines(width: 0), numberFormat: NumberFormat.compact()),
|
|
series: controller.getDefaultBarSeries(),
|
|
tooltipBehavior: TooltipBehavior(enable: true),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildMultipleSeriesBubbleChart() {
|
|
return MyCard.bordered(
|
|
borderRadiusAll: 4,
|
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
|
paddingAll: 24,
|
|
child: SfCartesianChart(
|
|
plotAreaBorderWidth: 0,
|
|
title: ChartTitle(text: 'World countries details'),
|
|
primaryXAxis: NumericAxis(majorGridLines: MajorGridLines(width: 0), title: AxisTitle(text: 'Literacy rate'), minimum: 60, maximum: 100),
|
|
primaryYAxis: NumericAxis(axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(width: 0), title: AxisTitle(text: 'GDP growth rate')),
|
|
series: controller.getMultipleBubbleSeries(),
|
|
legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap, position: LegendPosition.bottom),
|
|
tooltipBehavior: controller.bubbleTooltipBehavior,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _CustomColumnSeriesRenderer<T, D> extends ColumnSeriesRenderer<T, D> {
|
|
_CustomColumnSeriesRenderer(this.themeData);
|
|
|
|
final ThemeData themeData;
|
|
|
|
@override
|
|
ColumnSegment<T, D> createSegment() {
|
|
return _ColumnCustomPainter(themeData);
|
|
}
|
|
}
|
|
|
|
class _ColumnCustomPainter<T, D> extends ColumnSegment<T, D> {
|
|
_ColumnCustomPainter(this.themeData);
|
|
|
|
final ThemeData themeData;
|
|
|
|
List<Color> colorList = <Color>[
|
|
Color.fromRGBO(53, 92, 125, 1),
|
|
Color.fromRGBO(192, 108, 132, 1),
|
|
Color.fromRGBO(246, 114, 128, 1),
|
|
Color.fromRGBO(248, 177, 149, 1),
|
|
Color.fromRGBO(116, 180, 155, 1)
|
|
];
|
|
List<Color> colorListM3Light = [
|
|
Color.fromRGBO(6, 174, 224, 1),
|
|
Color.fromRGBO(99, 85, 199, 1),
|
|
Color.fromRGBO(49, 90, 116, 1),
|
|
Color.fromRGBO(255, 180, 0, 1),
|
|
Color.fromRGBO(150, 60, 112, 1)
|
|
];
|
|
List<Color> colorListM3Dark = [
|
|
Color.fromRGBO(255, 245, 0, 1),
|
|
Color.fromRGBO(51, 182, 119, 1),
|
|
Color.fromRGBO(218, 150, 70, 1),
|
|
Color.fromRGBO(201, 88, 142, 1),
|
|
Color.fromRGBO(77, 170, 255, 1),
|
|
];
|
|
|
|
@override
|
|
Paint getFillPaint() {
|
|
final Paint customerFillPaint = Paint();
|
|
colorList = themeData.useMaterial3 ? (themeData.brightness == Brightness.light ? colorListM3Light : colorListM3Dark) : colorList;
|
|
customerFillPaint.isAntiAlias = false;
|
|
customerFillPaint.color = colorList[currentSegmentIndex];
|
|
customerFillPaint.style = PaintingStyle.fill;
|
|
return customerFillPaint;
|
|
}
|
|
|
|
@override
|
|
Paint getStrokePaint() {
|
|
final Paint customerStrokePaint = Paint();
|
|
customerStrokePaint.isAntiAlias = false;
|
|
customerStrokePaint.color = Colors.transparent;
|
|
customerStrokePaint.style = PaintingStyle.stroke;
|
|
return customerStrokePaint;
|
|
}
|
|
|
|
@override
|
|
void onPaint(Canvas canvas) {
|
|
if (segmentRect != null) {
|
|
double x, y;
|
|
x = segmentRect!.center.dx;
|
|
y = segmentRect!.top;
|
|
double width = 0;
|
|
double height = 20;
|
|
width = segmentRect!.width;
|
|
final Paint paint = Paint();
|
|
paint.color = getFillPaint().color;
|
|
paint.style = PaintingStyle.fill;
|
|
final Path path = Path();
|
|
final double factor = segmentRect!.height * (1 - animationFactor);
|
|
path.moveTo(x - width / 2, y + factor + height);
|
|
path.lineTo(x, (segmentRect!.top + factor + height) - height);
|
|
path.lineTo(x + width / 2, y + factor + height);
|
|
path.lineTo(x + width / 2, segmentRect!.bottom + factor);
|
|
path.lineTo(x - width / 2, segmentRect!.bottom + factor);
|
|
path.close();
|
|
canvas.drawPath(path, paint);
|
|
}
|
|
}
|
|
}
|