data_detail.dart 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import 'package:application/view/home/data_detail/data_detail_bar_charts.dart';
  2. import 'package:application/view/home/data_detail/data_detail_cp.dart';
  3. import 'package:application/widget.dart';
  4. import 'package:common_pub/model/history_detail.dart';
  5. import 'package:common_pub/ui/history_detail/trace_bar.dart';
  6. import 'package:common_pub/ui/map_view/map_view.dart';
  7. import 'package:common_pub/ui/map_view/view_map_cp.dart';
  8. import 'package:common_pub/ui/map_view/view_map_image.dart';
  9. import 'package:common_pub/ui/map_view/view_map_touch.dart';
  10. import 'package:common_pub/ui/map_view/view_map_trace.dart';
  11. import 'package:common_pub/ui/map_view/view_plug_loading.dart';
  12. import 'data_detail_controller.dart';
  13. class DataDetailPage extends StatelessWidget {
  14. const DataDetailPage({super.key});
  15. @override
  16. Widget build(BuildContext context) {
  17. return GetBuilder(
  18. init: DataDetailController(),
  19. builder: (c) {
  20. return Container(
  21. height: double.infinity,
  22. width: double.infinity,
  23. color: const Color(0xffc9c0c0),
  24. alignment: Alignment.center,
  25. child: c.mapWatch != null
  26. ? content(context, c.mapWatch!, c)
  27. : noData());
  28. });
  29. }
  30. Widget noData() {
  31. return Center(
  32. child: Column(
  33. mainAxisSize: MainAxisSize.min,
  34. children: [
  35. Image.asset(Assets.imagesIcNoData, height: 64),
  36. const SizedBox(height: 25),
  37. const Text('没有数据, 请选择地图',
  38. style: TextStyle(color: Color(0xff707070), fontSize: 18.5)),
  39. ],
  40. ),
  41. );
  42. }
  43. static const cpColor = Color(0xffcc00ff);
  44. Widget content(
  45. BuildContext context, MapWatchService map, DataDetailController c) {
  46. return Obx(() {
  47. final children = <Widget>[
  48. ViewPlugLoading(map.plugMap),
  49. ViewMapImage(map.plugMap),
  50. ];
  51. final data = c.selectedDetail.value;
  52. if (data != null) {
  53. children.add(ViewMapCP(
  54. map.plugMap,
  55. cpWantAndHistoryList: data.controlPoints,
  56. isHideRouteBeforeStart: false,
  57. isShowPath: false,
  58. cpTheme: ViewMapCPTheme()
  59. ..cpJumpColor = cpColor
  60. ..cpPunchedColor = cpColor,
  61. ));
  62. children.add(ViewMapTrace(map.plugMap, data.traceList));
  63. }
  64. children.add(ViewMapTouch(map.plugMap));
  65. return Row(children: [
  66. Expanded(
  67. child: Column(
  68. children: [
  69. Expanded(
  70. child: ViewMapStack(plug: map.plugMap, children: children)),
  71. _traceBarView(c)
  72. ],
  73. )),
  74. _UserListView()
  75. ]);
  76. });
  77. }
  78. Widget _traceBarView(DataDetailController c) {
  79. final detail = c.selectedDetail.value;
  80. final children = <Widget>[];
  81. if (detail != null) {
  82. final data = detail.dataChartPage.pace.data
  83. .map((e) =>
  84. TraceBarData(DataOne(e.x, e.y).toPace())..ts = e.x.milliseconds)
  85. .toList();
  86. if (data.isNotEmpty) {
  87. final ts = data.first.ts - 1.seconds;
  88. if (ts > Duration.zero) {
  89. data.insert(0, TraceBarData(null)..ts = ts);
  90. }
  91. }
  92. children.addAll([
  93. const Text('配速(按时间)'),
  94. SizedBox(
  95. child: TraceBar(data, controller: c.traceBarController),
  96. )
  97. ]);
  98. }
  99. return Container(
  100. decoration: BoxDecoration(color: Colors.white),
  101. height: 73,
  102. width: double.infinity,
  103. child: Column(children: children),
  104. );
  105. }
  106. }
  107. class _UserListView extends GetView<DataDetailController> {
  108. @override
  109. Widget build(BuildContext context) {
  110. return Obx(() {
  111. return Container(
  112. width: 263,
  113. height: double.infinity,
  114. decoration: const BoxDecoration(color: Colors.white, boxShadow: [
  115. BoxShadow(color: Color(0x33000000), blurRadius: 4.3)
  116. ]),
  117. padding: const EdgeInsets.all(20),
  118. child: Column(
  119. children: [
  120. Row(
  121. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  122. children: [
  123. const Text('用户列表'),
  124. IconButton(
  125. onPressed: controller.selectedDetail.value != null
  126. ? () => controller.showDetail.value =
  127. !controller.showDetail.value
  128. : null,
  129. icon: const Icon(Icons.more_horiz)),
  130. ],
  131. ),
  132. Expanded(
  133. child: ListView(
  134. children: controller.showDetail.value
  135. ? _detailView()
  136. : controller.userList
  137. .map((element) => _userElem(element))
  138. .toList(),
  139. ))
  140. ],
  141. ));
  142. });
  143. }
  144. List<Widget> _detailView() {
  145. final detail = controller.selectedDetail.value!;
  146. return [
  147. DataDetailCP(cpList: detail.controlPoints),
  148. const SizedBox(height: 8),
  149. const DataDetailBarCharts(),
  150. ];
  151. }
  152. Widget _userElem(UserInfo data) {
  153. return Obx(() {
  154. final children = <Widget>[
  155. Container(
  156. width: double.infinity,
  157. height: 42,
  158. margin: const EdgeInsets.only(top: 8),
  159. padding: const EdgeInsets.only(left: 4),
  160. decoration: BoxDecoration(
  161. color: Colors.white,
  162. boxShadow: const [
  163. BoxShadow(color: Color(0x29000000), blurRadius: 3)
  164. ],
  165. borderRadius: BorderRadius.circular(3.56)),
  166. child: Row(
  167. children: [
  168. Container(
  169. height: double.infinity,
  170. width: 3.56,
  171. margin: const EdgeInsets.only(top: 8, bottom: 8, right: 3.55),
  172. decoration: BoxDecoration(
  173. color: data.data.oId == controller.selectedUserId.value
  174. ? Colors.orange
  175. : Colors.transparent,
  176. borderRadius: BorderRadius.circular(2.1)),
  177. ),
  178. Text(data.data.oName),
  179. const Spacer(),
  180. IconButton(
  181. onPressed: () {
  182. data.isExpand.value = !data.isExpand.value;
  183. },
  184. icon: Icon(data.isExpand.value
  185. ? Icons.arrow_drop_up
  186. : Icons.arrow_drop_down))
  187. ],
  188. ),
  189. )
  190. ];
  191. if (data.isExpand.value) {
  192. children.add(Column(
  193. children: data.data.list
  194. .map((element) => GestureDetector(
  195. onTap: () => controller.selectDetail(element, data),
  196. child: detailElem(element)))
  197. .toList(),
  198. ));
  199. }
  200. return Column(
  201. children: children,
  202. );
  203. });
  204. }
  205. Widget detailElem(DetailSimple detail) {
  206. return Container(
  207. margin: const EdgeInsets.only(left: 12, top: 2, bottom: 4),
  208. width: double.infinity,
  209. height: 54,
  210. padding: const EdgeInsets.fromLTRB(4, 6, 4, 6),
  211. decoration: BoxDecoration(
  212. color: Colors.white,
  213. borderRadius: BorderRadius.circular(3.5),
  214. boxShadow: const [
  215. BoxShadow(color: Color(0x33000000), blurRadius: 1.3)
  216. ]),
  217. child: Row(
  218. children: [
  219. Container(
  220. height: double.infinity,
  221. width: 3.56,
  222. margin: const EdgeInsets.only(right: 3.55),
  223. decoration: BoxDecoration(
  224. color: detail.gameId ==
  225. controller.selectedDetailSimple.value.gameId
  226. ? Colors.orange
  227. : Colors.transparent,
  228. borderRadius: BorderRadius.circular(2.1)),
  229. ),
  230. Expanded(
  231. child: Column(
  232. crossAxisAlignment: CrossAxisAlignment.start,
  233. children: [
  234. Text(detail.courseName,
  235. maxLines: 1, overflow: TextOverflow.ellipsis),
  236. Text(
  237. detail.actName,
  238. maxLines: 1,
  239. overflow: TextOverflow.ellipsis,
  240. ),
  241. ],
  242. )),
  243. const SizedBox(width: 12),
  244. Text(detail.isComplete ? '完赛' : '未完赛')
  245. ],
  246. ),
  247. );
  248. }
  249. }