You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
23 KiB
Dart

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:fl_chart/fl_chart.dart';
//import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
class ZptjBarChart extends StatefulWidget {
ZptjBarChart({this.statisType, this.data_ok = false, Key key}) : super(key: key);
String statisType; //统计类型
bool data_ok; //listZptjStatis 中的数据是否准备好
@override
State<StatefulWidget> createState() => ZptjBarChartState();
}
class ZptjBarChartState extends State<ZptjBarChart> {
static const Color red = const Color(0xffff5182);
static const Color blue = const Color(0xff0000ff);
static const Color leftBarColor = const Color(0xffff5182);
static const Color rightBarColor = const Color(0xff0000ff);
static const Color bottomBarColor = const Color(0xff939393);
static const Color gridColor = const Color(0xffe7e8ec);
static const double width = 7;
String _textBottom1;
String _textBottom2;
String _textTop1;
String _textTop2;
int _rate = 10; // today 字段放大倍率
int _rateCoord = 10000; // 坐标压缩倍率
int _interval = 20; // 坐标间隔
int _maxY = -1;
List<BarChartGroupData> _listBarData = [];
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void initState() {
super.initState();
getDataNew().then((value) {
_listBarData = value;
try_setState();
});
// ///获取点位信息数据
// if (!widget.data_ok) {
// //listZptjStatis 中的数据未准备好
// listZptjStatis.clear(); //最后需要显示的数据
// }
//
// if (listZptjStatis.isEmpty) {
// if (listDwinfoGetList2.isEmpty) {
// //若没有读取了点位数据,便需要先读取
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// });
// } else {
// //若已经读取了点位数据,便直接使用
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// }
// } else {
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// }
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text(mapStatisType[widget.statisType]['text']),
// centerTitle: true,
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(mapStatisType[widget.statisType]['text'],
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
alignment: Alignment(0, -0.85),
child: AspectRatio(
aspectRatio: 0.94, //宽高比
child: Card(
elevation: 4, //阴影高度
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
color: Colors.white,
child: Container(
padding: const EdgeInsets.only(top: 20),
child: (listAllStatisData.isEmpty || _listBarData.isEmpty)
? getMoreWidget(color: Colors.black38)
: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textTop1, style: TextStyle(color: leftBarColor, fontSize: 12)),
Expanded(
child: Text(''),
),
Text(_textTop2, style: TextStyle(color: rightBarColor, fontSize: 12)),
SizedBox(width: 3),
],
),
SizedBox(
height: 10,
),
BarChart(
BarChartData(
maxY: _maxY.toDouble() * 1.1,
groupsSpace: 6,
alignment: BarChartAlignment.spaceEvenly,
barTouchData: BarTouchData(
enabled: false,
),
//坐标数据
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
rotateAngle: 45,
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: bottomBarColor, fontSize: 10),
margin: 10,
getTitles: (double value) {
int i = value.toInt() - 1;
return '${listAllStatisData[i]['id']}. ${listAllStatisData[i]['dwmc']}';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: leftBarColor, fontSize: 10),
margin: 4, //边距
getTitles: (double value) {
value = value / _rateCoord; //坐标压缩别率
if (value.toInt() % _interval == 0) {
return '${(value / _rate).toInt()}'; //将左侧坐标放大 _rate 倍
} else {
return '';
}
},
),
rightTitles: SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: rightBarColor, fontSize: 10),
margin: 4,
getTitles: (double value) {
value = value / _rateCoord; //坐标压缩别率
if (value.toInt() % _interval == 0) {
return '${value.toInt()}';
} else {
return '';
}
},
),
),
//栅格线
gridData: FlGridData(
show: true,
checkToShowHorizontalLine: (value) => value % _rate == 0,
getDrawingHorizontalLine: (value) => FlLine(
color: gridColor,
strokeWidth: 1,
),
),
//边线
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: gridColor,
width: 2,
),
left: BorderSide(
color: leftBarColor,
width: 2,
),
right: BorderSide(
color: rightBarColor,
width: 2,
),
top: BorderSide(
color: Colors.transparent,
),
),
),
//图标数据
barGroups: _listBarData,
//barGroups: showingBarGroups,
),
),
SizedBox(height: 30),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textBottom1,
style: TextStyle(color: leftBarColor, fontSize: 12)),
Expanded(
child: Container(
alignment: Alignment.center,
child: Text('点位编号',
style: TextStyle(color: bottomBarColor, fontSize: 12)),
),
),
Text(_textBottom2,
style: TextStyle(color: rightBarColor, fontSize: 12)),
SizedBox(width: 3),
],
),
]),
),
),
),
),
);
}
List<int> bar_getAllSumNew(String field) {
int items = 0;
int sum = 0;
for (var item in listAllStatisData) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
Future<List<BarChartGroupData>> getDataNew() async {
String _field1 = '';
String _field2 = '';
_maxY = -1;
int len = listAllStatisData.length;
List<BarChartGroupData> listBarData = [];
switch (widget.statisType) {
case 'zptj':
_field1 = 'zp_today';
_field2 = 'zp_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1]}'; // 'all' 字段没有记录详情所以用bar_getAllSumCll()
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
case 'sh_hyc_tj':
_field1 = 'hyc_all';
_field2 = 'send_all';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩倍率
_interval = 2; // 坐标间隔
_textBottom1 = '已审核 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '已推送 ${bar_getAllSumNew(_field2)[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
/*
listAllStatisData =
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 53,
"zp_today": 1,
"sends": 1,
"send_all": 34,
"csnum": 1,
"fsnum": 1,
"cll_today": 23200,
"cll_all": 3242513
},
...
]
*/
case 'clltj':
_field1 = 'cll_today';
_field2 = 'cll_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1] ~/ _rateCoord} 万辆';
_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1] ~/ _rateCoord} 万辆';
_textTop1 = '今日(万辆)';
_textTop2 = '(万辆)合计';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
default:
break;
}
return listBarData;
}
Future<List<BarChartGroupData>> getData() async {
String _field1 = '';
String _field2 = '';
_maxY = -1;
int len = listZptjStatis.length;
List<BarChartGroupData> listBarData = [];
switch (widget.statisType) {
case 'zptj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSum('today')[1]}';
_textBottom2 = '总共 ${bar_getAllSumCll('all')[1]}'; // 'all' 字段没有记录详情所以用bar_getAllSumCll()
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1]["total"] * _rate).toDouble(),
listZptjStatis[i][_field2].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1]["total"] * _rate > _maxY
? listZptjStatis[i][_field1]["total"] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
break;
case 'sh_hyc_tj':
_field1 = 'total';
_field2 = 'sends';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 2; // 坐标间隔
_textBottom1 =
'已审核 ${bar_getAllSumCll('total')[1]}'; // 'total' 字段没有记录详情所以用bar_getAllSumCll()
_textBottom2 = '已推送 ${bar_getAllSum('sends')[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1] * _rate).toDouble(),
listZptjStatis[i][_field2]["total"].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1] * _rate > _maxY
? listZptjStatis[i][_field1] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2]["total"] > _maxY
? listZptjStatis[i][_field2]["total"]
: _maxY;
}
break;
case 'clltj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumCll('today')[1] ~/ _rateCoord} 万辆';
_textBottom2 = '总共 ${bar_getAllSumCll('all')[1] ~/ _rateCoord} 万辆';
_textTop1 = '今日(万辆)';
_textTop2 = '(万辆)合计';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1] * _rate).toDouble(),
listZptjStatis[i][_field2].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1] * _rate > _maxY
? listZptjStatis[i][_field1] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
break;
default:
break;
}
return listBarData;
}
BarChartGroupData makeGroupData(int x, double y1, double y2) {
return BarChartGroupData(barsSpace: 0, x: x, barRods: [
BarChartRodData(
y: y1,
colors: [leftBarColor],
width: width,
borderRadius: const BorderRadius.all(Radius.zero),
),
BarChartRodData(
y: y2,
colors: [rightBarColor],
width: width,
borderRadius: const BorderRadius.all(Radius.zero),
),
]);
}
//获取已审核黑烟车统计数据App.Car_Statis.GetStaHyc
//{
// "ret": 200,
// "data": {
// "total": 40,
// "sends": {
// "total": 0,
// "data": []
// },
// "csnum": {
// "total": 0,
// "data": []
// },
// "fsnum": {
// "total": 0,
// "data": []
// }
// },
// "msg": ""
// }
//获取抓拍统计数据App.Car_Statis.GetStaYjxx
//{
// "ret": 200,
// "data": {
// "today": {
// "total": 0,
// "data": []
// },
// "all": 40
// },
// "msg": ""
// }
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:抓拍统计的'today'、all审核统计的"total"、"sends"
List<int> bar_getAllSum(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field]["total"] > 0) {
items++;
sum += item[field]["total"];
}
}
return [items, sum];
}
//获取车流量统计数据App.Car_Statis.GetStaCll
//{
// "ret": 200,
// "data": {
// "today": 7010,
// "all": 1640350
// },
// "msg": ""
//}
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:车流量统计的'today'、all
List<int> bar_getAllSumCll(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
}