ShotStats.jsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // components
  2. import Spring from '@components/Spring';
  3. import LegendItem from '@ui/LegendItem';
  4. import {ResponsiveContainer, Scatter, ScatterChart, ReferenceLine, Cell, Tooltip, XAxis} from 'recharts';
  5. import ClubInfo from '@components/ClubInfo';
  6. import TabButton from '@ui/TabButton';
  7. import ChartTooltip from '@ui/ChartTooltip';
  8. // hooks
  9. import {useState} from 'react';
  10. import {useThemeProvider} from '@contexts/themeContext';
  11. const data = {
  12. first: [
  13. {target: 61, miss: 20},
  14. {target: 92, miss: 43},
  15. {target: 49, miss: 39},
  16. {target: 84, miss: 27},
  17. {target: 83, miss: 45},
  18. {target: 43, miss: 17},
  19. {target: 87, miss: 10},
  20. {target: 78, miss: 56},
  21. {target: 15, miss: 34},
  22. {target: 48, miss: 14},
  23. {target: 74, miss: 18},
  24. {target: 35, miss: 92}
  25. ],
  26. second: [
  27. {target: 70, miss: 27},
  28. {target: 43, miss: 57},
  29. {target: 53, miss: 27},
  30. {target: 14, miss: 71},
  31. {target: 23, miss: 19},
  32. {target: 75, miss: 92},
  33. {target: 33, miss: 15},
  34. {target: 26, miss: 28},
  35. {target: 97, miss: 32},
  36. {target: 25, miss: 34},
  37. {target: 84, miss: 12},
  38. {target: 93, miss: 41}
  39. ]
  40. }
  41. const ShotsStats = () => {
  42. const [selectedHalf, setSelectedHalf] = useState('first');
  43. const {direction} = useThemeProvider();
  44. const isRTL = direction === 'rtl';
  45. const infoStyles = {
  46. position: 'absolute',
  47. bottom: 0,
  48. }
  49. const CustomScatterShape = ({cx, cy, fill, ...props}) => {
  50. const isDominant = props.dom === props.dataKey;
  51. return (
  52. <svg width="10" height="217" viewBox="0 0 10 222" x={cx} y={cy} fill="none"
  53. xmlns="http://www.w3.org/2000/svg">
  54. {
  55. isDominant &&
  56. <>
  57. <path d="M5 25V215" stroke="url(#dashed)" strokeWidth="4" strokeLinecap="round"
  58. strokeDasharray="8 8"/>
  59. <path fillRule="evenodd" clipRule="evenodd"
  60. d="M5 10C7.76142 10 10 7.76142 10 5C10 2.23858 7.76142 0 5 0C2.23858 0 0 2.23858 0 5C0 7.76142 2.23858 10 5 10Z"
  61. fill={fill}/>
  62. </>
  63. }
  64. <defs>
  65. <linearGradient id="dashed" x1="3" y1="145" x2="3" y2="2" gradientUnits="userSpaceOnUse">
  66. <stop stopColor="var(--widget)"/>
  67. <stop offset="0.795555" stopColor="var(--border)"/>
  68. </linearGradient>
  69. </defs>
  70. </svg>
  71. );
  72. }
  73. return (
  74. <Spring className="card h-2 d-flex flex-column p-relative">
  75. <div className="d-flex flex-column g-16 flex-1">
  76. <div className="card_header d-flex flex-column g-20">
  77. <ClubInfo title="Shots stats" subtitle="Manchester City" id="mancity"/>
  78. <div className="tab-nav col-2">
  79. <TabButton title="First half" active={selectedHalf === 'first'}
  80. onClick={() => setSelectedHalf('first')}/>
  81. <TabButton title="Second half" active={selectedHalf === 'second'}
  82. onClick={() => setSelectedHalf('second')}/>
  83. </div>
  84. </div>
  85. <ResponsiveContainer className="flex-1" width="100%" height="100%">
  86. <ScatterChart margin={false} data={data[selectedHalf]}>
  87. <XAxis dataKey="name" reversed={isRTL} hide/>
  88. <Scatter dataKey="miss" shape={CustomScatterShape}>
  89. {
  90. data[selectedHalf].map((entry, index) => {
  91. return (
  92. <Cell key={`cell-${index}`}
  93. fill="var(--salmon)"
  94. dom={entry.miss > entry.target ? 'miss' : 'target'}
  95. dataKey="miss"/>
  96. )
  97. })
  98. }
  99. </Scatter>
  100. <Scatter dataKey="target" shape={CustomScatterShape}>
  101. {
  102. data[selectedHalf].map((entry, index) => {
  103. return (
  104. <Cell key={`cell-${index}`}
  105. fill="var(--grass)"
  106. dom={entry.miss > entry.target ? 'miss' : 'target'}
  107. dataKey="target"/>
  108. )
  109. })
  110. }
  111. </Scatter>
  112. <ReferenceLine y={50} stroke="var(--grass)" strokeWidth={2} strokeDasharray="4 2"/>
  113. <Tooltip cursor={false} content={ChartTooltip} multi={false}/>
  114. </ScatterChart>
  115. </ResponsiveContainer>
  116. </div>
  117. <div className="card_footer d-flex flex-column g-8" style={infoStyles}>
  118. <div>
  119. <span className="h1">18</span> shots
  120. </div>
  121. <div className="d-flex g-14">
  122. <LegendItem color="salmon" text="miss"/>
  123. <LegendItem color="grass" text="On target"/>
  124. </div>
  125. </div>
  126. </Spring>
  127. )
  128. }
  129. export default ShotsStats