page.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. import React from 'react';
  2. import './index.less';
  3. import Page from '@src/containers/Page';
  4. // import LineChart from '@src/components/LineChart';
  5. import BarChart from '@src/components/BarChart';
  6. import PieChart from '@src/components/PieChart';
  7. // import { getMap } from '@src/services/Tools';
  8. import UserLayout from '../../../layouts/User';
  9. import UserTable from '../../../components/UserTable';
  10. import UserAction from '../../../components/UserAction';
  11. import Select from '../../../components/Select';
  12. import menu from '../index';
  13. import Tabs from '../../../components/Tabs';
  14. // import { QuestionDifficult } from '../../../../Constant';
  15. const columns = [
  16. {
  17. key: 'title',
  18. title: '',
  19. render(text) {
  20. return <b>{text}</b>;
  21. },
  22. },
  23. {
  24. key: 'progress',
  25. title: '进度',
  26. render() {
  27. return (
  28. <div className="v">
  29. <div className="t">50%</div>
  30. <div className="d">已做20道</div>
  31. </div>
  32. );
  33. },
  34. },
  35. {
  36. key: 'ratio',
  37. title: '正确率',
  38. render() {
  39. return (
  40. <div className="v">
  41. <div className="t">100%</div>
  42. <div className="d">899/899</div>
  43. </div>
  44. );
  45. },
  46. },
  47. {
  48. key: 'time',
  49. title: '平均用时',
  50. help: '',
  51. },
  52. ];
  53. // const QuestionDifficultMap = getMap(QuestionDifficult, 'value', 'label');
  54. function pieOption1(value, text, subtext) {
  55. return {
  56. title: {
  57. text,
  58. textAlign: 'center',
  59. textVerticalAlign: 'middle',
  60. subtext,
  61. top: '28%',
  62. left: '48%',
  63. },
  64. // value < 50 ? '#f19057' :
  65. color: ['#6966fb', '#f7f7f7'],
  66. series: [
  67. {
  68. type: 'pie',
  69. radius: ['90%', '100%'],
  70. label: {
  71. show: false,
  72. },
  73. data: [value, 100 - value],
  74. },
  75. ],
  76. };
  77. }
  78. function barOption1(avgTotal, avgCorrect, avgIncorrent) {
  79. return {
  80. xAxis: {
  81. type: 'category',
  82. axisTick: { show: false },
  83. axisLine: { lineStyle: { color: '#D1D6DF' } },
  84. splitLine: { show: false },
  85. data: [
  86. {
  87. value: 'Avg Time\nTotal',
  88. textStyle: { color: '#686872', fontWeight: '500', fontSize: 14, lineHeight: 20 },
  89. },
  90. {
  91. value: 'Avg Time\nCorrect',
  92. textStyle: { color: '#686872', fontWeight: '500', fontSize: 14, lineHeight: 20 },
  93. },
  94. {
  95. value: 'Avg Time\nIncorrect',
  96. textStyle: { color: '#686872', fontWeight: '500', fontSize: 14, lineHeight: 20 },
  97. },
  98. ],
  99. },
  100. yAxis: {
  101. show: false,
  102. min: 0,
  103. max: 100,
  104. axisTick: { show: false },
  105. axisLine: { show: false },
  106. splitLine: { show: false },
  107. },
  108. grid: { width: 300, left: '10%' },
  109. series: {
  110. type: 'bar',
  111. barWidth: 50,
  112. data: [
  113. {
  114. value: avgTotal,
  115. name: 'Avg Time\nTotal',
  116. itemStyle: { color: '#92AFD2' },
  117. label: {
  118. show: true,
  119. position: 'top',
  120. formatter: `{a|${avgTotal}}`,
  121. rich: { a: { fontSize: 16, fontWeight: 'bold', color: '#686872' } },
  122. },
  123. },
  124. {
  125. value: avgCorrect,
  126. name: 'Avg Time\nCorrect',
  127. itemStyle: { color: '#989FC1' },
  128. label: {
  129. show: true,
  130. position: 'top',
  131. formatter: `{a|${avgCorrect}}`,
  132. rich: { a: { fontSize: 16, fontWeight: 'bold', color: '#686872' } },
  133. },
  134. },
  135. {
  136. value: avgIncorrent,
  137. name: 'Avg Time\nIncorrect',
  138. itemStyle: { color: '#BFD4EE' },
  139. label: {
  140. show: true,
  141. position: 'top',
  142. formatter: `{a|${avgIncorrent}}`,
  143. rich: { a: { fontSize: 16, fontWeight: 'bold', color: '#686872' } },
  144. },
  145. },
  146. ],
  147. },
  148. };
  149. }
  150. function barOption2(title, subTitle, data) {
  151. return {
  152. title: {
  153. text: title,
  154. subtext: subTitle,
  155. textStyle: { fontSize: 16 },
  156. },
  157. tooltip: {
  158. trigger: 'axis',
  159. },
  160. color: '#989FC1',
  161. dataset: {
  162. source: [['type', 'self'], ...data],
  163. },
  164. grid: { left: 30, right: 30, height: 250 },
  165. xAxis: {
  166. type: 'category',
  167. axisLabel: { color: '#686872' },
  168. axisLine: { lineStyle: { color: '#D1D6DF' } },
  169. },
  170. yAxis: {
  171. type: 'value',
  172. min: 0,
  173. max: 100,
  174. axisLabel: { color: '#686872' },
  175. axisLine: { lineStyle: { color: '#D1D6DF' } },
  176. },
  177. series: {
  178. type: 'bar',
  179. barWidth: 40,
  180. },
  181. };
  182. }
  183. function barOption3(titles, source, data1, data2, color1, color2) {
  184. return {
  185. title: [
  186. {
  187. text: titles[0],
  188. textStyle: { fontSize: 16, fontWeight: 'bold', color: '#686872' },
  189. left: 30,
  190. top: 15,
  191. },
  192. {
  193. text: titles[1],
  194. textStyle: { fontSize: 16, fontWeight: 'bold', color: '#686872' },
  195. left: 100,
  196. top: 15,
  197. },
  198. {
  199. text: titles[2],
  200. textStyle: { fontSize: 16, fontWeight: 'bold', color: '#686872' },
  201. left: 430,
  202. top: 15,
  203. },
  204. ],
  205. grid: [{ width: 200, x: 100, bottom: 30 }, { width: 200, x: 430, bottom: 30 }],
  206. xAxis: [
  207. {
  208. gridIndex: 0,
  209. show: false,
  210. axisTick: { show: false },
  211. axisLine: { show: false },
  212. splitLine: { show: false },
  213. },
  214. {
  215. gridIndex: 1,
  216. show: false,
  217. axisTick: { show: false },
  218. axisLine: { show: false },
  219. splitLine: { show: false },
  220. },
  221. ],
  222. yAxis: [
  223. {
  224. gridIndex: 0,
  225. type: 'category',
  226. axisTick: { show: false },
  227. axisLine: { show: false },
  228. splitLine: { show: false },
  229. offset: 15,
  230. data: source,
  231. axisLabel: { color: '#686872', fontSize: 12 },
  232. },
  233. {
  234. gridIndex: 1,
  235. type: 'category',
  236. axisTick: { show: false },
  237. axisLine: { show: false },
  238. splitLine: { show: false },
  239. axisLabel: { show: false },
  240. },
  241. ],
  242. series: [
  243. {
  244. type: 'bar',
  245. xAxisIndex: 0,
  246. yAxisIndex: 0,
  247. barWidth: 24,
  248. data: data1.map((item, index) => ({
  249. value: item,
  250. itemStyle: { color: index % 2 ? color1[0] : color1[1] },
  251. label: {
  252. show: true,
  253. color: '#303036',
  254. align: 'right',
  255. position: [250, 5],
  256. fontSize: 12,
  257. formatter: item,
  258. },
  259. })),
  260. },
  261. {
  262. type: 'bar',
  263. xAxisIndex: 1,
  264. yAxisIndex: 1,
  265. barWidth: 24,
  266. data: data2.map((item, index) => ({
  267. value: item,
  268. itemStyle: { color: index % 2 ? color2[0] : color2[1] },
  269. label: {
  270. show: true,
  271. color: '#303036',
  272. align: 'right',
  273. fontSize: 12,
  274. position: [260, 5],
  275. formatter: item,
  276. },
  277. })),
  278. },
  279. ],
  280. };
  281. }
  282. export default class extends Page {
  283. initState() {
  284. return {
  285. filterMap: {},
  286. data: [
  287. { title: '语法SC', time: '1min20s' },
  288. { title: '逻辑CR', time: '1min20s' },
  289. { title: '阅读RC', time: '1min20s' },
  290. ],
  291. selectList: [],
  292. tab1: '1',
  293. tab2: '1',
  294. tab3: '1',
  295. };
  296. }
  297. onTabChange(tab) {
  298. this.setState({ tab1: tab });
  299. }
  300. onTabChange1(tab) {
  301. this.setState({ tab2: tab });
  302. }
  303. onTabChange2(tab) {
  304. this.setState({ tab3: tab });
  305. }
  306. onFilter(value) {
  307. this.setState({ filterMap: value });
  308. }
  309. onDataChange(page) {
  310. this.setState({ page, allChecked: false, selectList: [] });
  311. }
  312. onAction() {}
  313. onSelect(selectList) {
  314. this.setState({ selectList });
  315. }
  316. renderView() {
  317. const { config } = this.props;
  318. return <UserLayout active={config.key} menu={menu} center={this.renderTable()} />;
  319. }
  320. renderTable() {
  321. const { tab1, tab2, tab3, filterMap = {}, data } = this.state;
  322. return (
  323. <div className="table-layout">
  324. <Tabs
  325. border
  326. type="division"
  327. theme="theme"
  328. size="small"
  329. space={2.5}
  330. width={100}
  331. active={tab1}
  332. tabs={[{ key: '1', title: '练习' }, { key: '2', title: '模考' }]}
  333. onChange={key => this.onTabChange(key)}
  334. />
  335. <UserAction
  336. search
  337. selectList={[
  338. {
  339. label: '123',
  340. children: [
  341. {
  342. key: 'one',
  343. default: '1',
  344. select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
  345. },
  346. {
  347. key: 'two',
  348. be: 'one',
  349. placeholder: '全部',
  350. selectMap: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
  351. },
  352. ],
  353. },
  354. {
  355. label: '123',
  356. right: true,
  357. select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
  358. },
  359. ]}
  360. filterMap={filterMap}
  361. onFilter={value => this.onFilter(value)}
  362. />
  363. <div className="title">整体情况</div>
  364. <UserTable size="small" columns={columns} data={data} />
  365. <div className="title">
  366. 单项分析
  367. <Select
  368. size="small"
  369. theme="default"
  370. value={tab2}
  371. list={[{ key: '1', title: '全部' }, { key: '2', title: '语法' }]}
  372. onChange={({ key }) => this.onTabChange1(key)}
  373. />
  374. </div>
  375. <Tabs
  376. border
  377. type="line"
  378. theme="theme"
  379. size="small"
  380. width={80}
  381. active={tab3}
  382. tabs={[{ key: '1', title: '基本情况' }, { key: '2', title: '难度分析' }, { key: '3', title: '考点分析' }]}
  383. onChange={key => this.onTabChange2(key)}
  384. />
  385. {this[`renderTab${tab3}`]()}
  386. </div>
  387. );
  388. }
  389. renderTab1() {
  390. return (
  391. <div className="tab-1-layout">
  392. <div className="block">
  393. <div className="chart">
  394. <PieChart height={110} width={110} option={pieOption1(10, '123', '321')} />
  395. </div>
  396. <div className="value">
  397. <div className="total">共200题</div>
  398. <div className="item">
  399. <div className="t">已做</div>
  400. <div className="v">
  401. <b>265</b>题
  402. </div>
  403. </div>
  404. <div className="item">
  405. <div className="t">剩余</div>
  406. <div className="v">
  407. <b>8</b>题
  408. </div>
  409. </div>
  410. <div className="item">
  411. <div className="t">正确率</div>
  412. <div className="v">
  413. <b>50%</b>
  414. </div>
  415. </div>
  416. <div className="item">
  417. <div className="t">全站</div>
  418. <div className="v">
  419. <b>23%</b>
  420. </div>
  421. </div>
  422. </div>
  423. </div>
  424. <div className="block">
  425. <BarChart height={300} option={barOption1(10, 20, 30)} />
  426. </div>
  427. </div>
  428. );
  429. }
  430. renderTab2() {
  431. return (
  432. <div className="tab-2-layout">
  433. <BarChart
  434. height={350}
  435. option={barOption2('平均正确率80%', '正确率', [['easy', 10], ['Medium', 30], ['Hard', 40]])}
  436. />
  437. </div>
  438. );
  439. }
  440. renderTab3() {
  441. return (
  442. <div className="tab-3-layout">
  443. <BarChart
  444. height={350}
  445. option={barOption3(
  446. ['知识点', '正确率分析', '用时分析'],
  447. ['Idiom', 'Comparison', 'Verb', 'Pronoun', 'Modifier', 'Parallelism'],
  448. [10, 12, 12, 13, 14, 15],
  449. [10, 12, 12, 13, 14, 15],
  450. ['#92AFD2', '#BFD4EE'],
  451. ['#989FC1', '#CCCCDC'],
  452. )}
  453. />
  454. </div>
  455. );
  456. }
  457. }