data_detail.dart 8.2 KB

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